
Callable 和 Runable 对比: 比如Callable 是你自己,你想通过你的女朋友 Runable 认识她的闺蜜 Thread


- Callable 是 java.util 包下 concurrent 下的接口,有返回值,可以抛出被检查的异常
- Runable 是 java.lang 包下的接口,没有返回值,不可以抛出被检查的异常
- 二者调用的方法不同,run()/ call()
同样的 Lock 和 Synchronized 二者的区别,前者是java.util 下的接口 后者是 java.lang 下的关键字。
java
new Thread(new Runnable()).start(); //创建一个线程去执行一个没有返回值的任务。
new Thread(new FutureTask<V>()).start(); //FutureTask实现了 RunnableFuture接口,而 RunnableFuture又继承了Runnable。所以 Thread 觉得它是 Runnable,就接收了它。
new Thread(new FutureTask<V>(Callable)).start();代码测试
java
package com.mystpet.Callable;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallableTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyThread thread = new MyThread();
FutureTask<Integer> futureTask = new FutureTask<>(thread);
new Thread(futureTask,"A").start();
new Thread(futureTask,"B").start();
Integer integer=futureTask.get();
System.out.println(integer);
}
}
class MyThread implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("call");
return 1024;
}
}运行结果:

A与B共用的是同一个 futureTask 对象。
缓存机制:
FutureTask内部维护了一个state(状态机)。只执行一次:当线程 A 拿到
futureTask并成功调用了call()方法后,FutureTask会将状态从NEW更新为COMPLETING,最后变为NORMAL(完成)。结果复用:当线程 B 启动时,它会检查
futureTask的状态。发现任务已经执行过或正在执行,它就不会再重复调用call()方法,而是直接等待结果。
细节: 1、有缓存
2、结果可能需要等待,会阻塞!