1. 多线程是什么?待更新
2. 多线程的实现方式
① 继承 Thread
② 实现 Runnable
③ 实现 Callable
3. Runnable 很熟悉,就是 new 一个 Thread 然后在里面放入实现 Runnable 接口的实现类。
其实 Callable 其实是也是跟 Runnable 一样,但是 Thread 不能直接认识到 Callable 接口的实现类,需要一个中间人。通过查找源码可知,其实 Runnable 接口其实是跟 Callable 接口有关联的,但是不是直接关联,而是间接关联,具体这个小三就是 FutureTask ,看官方文档。
点进去看一下,是什么东西
这也太棒了吧。FutureTask 竟然构造方法里面有 Callable,那么问题解决了。
我们只要 new 一个 FutureTask 然后传入 Callable 接口的实现类,那么使用 Callable 来实现线程也就 no problem 了。
呐,源码都给你扣过来啦。
知道官方文档的重要性了吧。留言邮箱,我来发你官方文档(程序员必备)
上面已经清晰的解释了怎么去实现了,下面还是给个实现的代码吧。
package CallableTest;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallableTest {
public static void main(String[] args) {
// 使用 Runnable 接口实现线程
new Thread(new RunnableImpl()).start();
// 使用 Callabble 接口实现线程
FutureTask futureTask = new FutureTask(new CallableImpl());
new Thread(futureTask).start();
try {
String res = (String) futureTask.get();
System.out.println(res);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
class CallableImpl implements Callable{
@Override
public String call() throws Exception {
System.out.println("正在使用 callable 来使用多线程.....");
return "ok";
}
}
class RunnableImpl implements Runnable{
@Override
public void run() {
System.out.println("正在使用 runnable 来使用多线程.....");
}
}
相信看了上面,应该不会还不知道怎么实现吧,,但是呢,有些东西,知其然,更要知其所以然。知道他怎么实现,更要知道为什么要这样干,Runnable 接口直接搞上不就行了,还省去一步中间商赚时间、空间复杂度。
嘿嘿!那你要这样想了,没有一个框架是没有作用而出现的,可能有,但是一定不会收到重视,竟然收到重视,那一定有他的独特之处。
我们细微的观察一下,这个 Callable 的里面有一个方法,call
他的返回值是 V 哦,这意味着不再是之前的 Runnable 接口的那个 run 方法了,run 方法的返回值是个 void ,这很不美丽。有时候我们更多的希望程序给我们一个反馈或者执行的接口,那么有个返回接口,毋庸置疑提高了我们代码的可读性、程序的逻辑严谨性。
Runnale 接口与 Callable 接口的区别其实上面的介绍已经全部展现出来了1. Runnable 接口的 run 方法没有返回值,Callable 的 call 方法有返回值;
2. Runnable 接口的 run 方法不用处理异常,Callable 的 call 方法需要处理异常;
3. Runnable 接口实现线程是直接放进去 Thread 里面,Callable 需要一个中间人 FutureTask 来引导。
生产者,消费者 demo
package ProvideCustomer;
import java.util.concurrent.FutureTask;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class PCTest {
public static void main(String[] args) {
ProviderCustomer providerCustomer = new ProviderCustomer();
new Thread(new FutureTask(()->{
for (int i = 0; i < 10; i++) {
providerCustomer.provider1();
}
return null;
}), "张三").start();
new Thread(new FutureTask(()->{
for (int i = 0; i < 10; i++) {
providerCustomer.provider2();
}
return null;
}), "王五").start();
new Thread(new FutureTask(()->{
for (int i = 0; i < 10; i++) {
providerCustomer.customer1();
}
return null;
}), "李四").start();
new Thread(new FutureTask(()->{
for (int i = 0; i < 10; i++) {
providerCustomer.customer2();
}
return null;
}), "赵六").start();
// 上面的写法等价于这个
//Callable callable = new Callable() {
// @Override
// public Object call() throws Exception {
// providerCustomer.customer();
// providerCustomer.provider();
// return null;
// }
//};
//FutureTask futureTask = new FutureTask(callable);
//new Thread(futureTask).start();
}
}
class ProviderCustomer{
private int ticket = 0;
// 锁
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
private Condition condition4 = lock.newCondition();
public void provider1() {
lock.lock();
try {
while (ticket > 0) {
// 还有商品那就等待吧
condition1.await();
}
ticket++;
// 没有商品,生产并通知消费者消费
System.out.println("生产者" + Thread.currentThread().getName() + "生产产品" + ticket);
condition3.signal();
} catch (Exception e) {
System.out.println(e.toString());
} finally {
lock.unlock();
}
}
public void provider2() {
lock.lock();
try {
while (ticket > 0) {
// 还有商品那就等待吧
condition2.await();
}
ticket++;
// 没有商品,生产并通知消费者消费
System.out.println("生产者" + Thread.currentThread().getName() + "生产产品" + ticket);
condition4.signal();
} catch (Exception e) {
System.out.println(e.toString());
} finally {
lock.unlock();
}
}
public void customer1(){
lock.lock();
try{
while (ticket <= 0){
// 还有商品那就等待吧
condition3.await();
}
ticket--;
// 消费商品,并通知生产者生产
System.out.println("消费者" + Thread.currentThread().getName() + "消费产品" + ticket);
condition2.signal();
}catch (Exception e){
System.out.println(e.toString());
}finally {
lock.unlock();
}
}
public void customer2(){
lock.lock();
try{
while (ticket <= 0){
// 还有商品那就等待吧
condition4.await();
}
ticket--;
// 消费商品,并通知生产者生产
System.out.println("消费者" + Thread.currentThread().getName() + "消费产品" + ticket);
condition1.signal();
}catch (Exception e){
System.out.println(e.toString());
}finally {
lock.unlock();
}
}
}
持续更新中........
有什么错误恳请留言指出,希望更新其他内容也可留言.



