Callable接口的使用
//比较两个接口
//实现Runnable接口
class MyThread1 implements Runnable {
@Override
public void run() {
}
}
//实现Callable接口
class MyThread2 implements Callable {
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName() + " 进入Callable");
return 200;
}
}
public class Demo1 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
new Thread(new MyThread1(), "AA").start();
// new Thread(new MyThread2(), "BB").start(); 报错
//FutureTask -->Runnable接口的实现类
FutureTask<Integer> futureTask1 = new FutureTask<>(new MyThread2());
//lam表达式
FutureTask<Integer> futureTask2 = new FutureTask<>(()->{
System.out.println(Thread.currentThread().getName() + " 进入Callable");
return 300;});
new Thread(futureTask2, "AA").start();
// new Thread(futureTask1, "BB").start();
while (!futureTask2.isDone()) {
System.out.println("wait......");
}
System.out.println(futureTask2.get());
System.out.println(futureTask2.get());//只计算一次
// System.out.println(futureTask1.get());
System.out.println(Thread.currentThread().getName() + "over");
//FutureTask原理 未来任务
/**
* 举例:
* 1.老师上课口渴了没水喝,跑去买水不合适,讲课线程继续,单开启另外线程,让班长去买水,把水买回来放那,老师需要的时候直接get()
* 2。三个同学,三个计算任务,我是主线程需要统计他们计算的结果, 假设第二个同学计算量很大,
* 我从第一个同学开始汇总,到了第二个同学,他还没计算好, 我单独给第二个同学开一个线程让他继续计算,我去汇总第三个同学。
* 等我汇总完了第三个同学, 再回过头来等第二个同学计算完,并汇总。
*
* 汇总一次
*/
}
}
FutureTask原理
举例:
1.老师上课口渴了没水喝,跑去买水不合适,讲课线程继续,单开启另外线程,让班长去买水,把水买回来放那,老师需要的时候直接get()
2.三个同学,三个计算任务,我是主线程需要统计他们计算的结果, 假设第二个同学计算量很大,我从第一个同学开始汇总,到了第二个同学,他还没计算好, 我单独给第二个同学开一个线程让他继续计算,我去汇总第三个同学。等我汇总完了第三个同学, 再回过头来等第二个同学计算完,并汇总。
Runable接口和Callable接口区别
- 是否有返回值, Callable有返回值
- 是否抛出异常, 无法计算结果会有异常抛出
- 实现方法名称不同, Runable接口是run方法, Callable接口是call方法
想要通过Callable接口创建线程,必须得通过Runnable接口的实现类 FutureTask,FutureTask构造可以传递Callable,然后new Thread,放入FutureTask