多线程的开启方式
继承Thread类,实现Runnable接口,实现Callable接口。
前两者是我们常见的多线程实现方式,就不详细介绍了。
实现Callable接口,与前两者不同是带有返回值,在之前的单线程中,如果中间有一个任务需要计算很长时间,那么就可以另开辟一个线程去执行它,最终把结果汇总就可以了,不会阻塞线程。
如下图:
Callable实现方式用到了适配器模式。
适配器模式就是让两个没有关系的接口,通过中间类产生关系。
比如:
new Thread();我们都知道需要在构造里面传一个Runnable接口的实例才能开启线程。那么Callable怎么才能传进去这个构造里边呢。需要借助FutureTask(将来的任务)这个类把Callable接口进行封装,这个类刚好构造方法里面可以传一个Callable接口实例,这个类又实现了Runnable接口。
例子:
需要让两个线程执行的结果相加,就可以使用Callable接口
代码如下:
public class CallableDemo implements Callable<Integer> {
@Override
public Integer call() throws Exception {
//模拟程序运行时间。
Thread.sleep(2000);
return 1024;
}
//主函数
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<Integer> futureTask = new FutureTask<>(new CallableDemo());
new Thread(futureTask,"AA").start(); //开启一个线程,
int a = 100;
//最后再来取值,
// 如果线程AA还没计算完成来取值的话会造成线程一直等待直到计算成功程序才会往下执行。
Integer integer = futureTask.get();
System.out.println(Thread.currentThread().getName()+"\t"+(a+integer));
}
}
适配器模式:
FutureTask 类实现了Runnable接口并且构造里边可以传一个Callable接口实例进行封装。最后Thread类构造里面接受一个Runnable实例,虽然Runnable接口和Callable接口直接没关系但是通过中间FutureTask类之间产生了关系。