认识Callable接口
Runnable接口和Callable接口的不同
-
callable接口,1.可以有返回值,2.可以抛出异常,3.调用方法不同,
-
Runnable接口不可以
-
实现Callable接口调用多线程,需要用到一个适配器模式
-
适配器模式(Adapter Pattern):将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。
-
因为Thread类只能接受Runnable接口的实现类,而不能直接接受Callable接口的实现类
-
而FutureTask类继承了Runnable接口的实现类RunnableFuture,并且能接受Callable接口的实现类作为参数,这样就可以进行一个转换,从而调用实现了Callable接口类的线程
细节方面,如果增加一个线程,结果会只输出一次,因为Callable会有缓存,执行同一个线程结果会被缓存(提高效率)
new Thread(futureTask,"B").start();
/***
* callable接口,1.可以有返回值,2.可以抛出异常,3.调用方法不同,
* Runnable接口不可以
*
* 实现Callable接口调用多线程,需要用到一个适配器模式
* 适配器模式(Adapter Pattern):将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。
*
* 因为Thread类只能接受Runnable接口的实现类,而不能直接接受Callable接口的实现类
* 而FutureTask类继承了Runnable接口的实现类RunnableFuture,并且能接受Callable接口的实现类作为参数,这样就可以进行一个转换,从而调用实现了Callable接口类的线程
*/
public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyThread myThread = new MyThread();
FutureTask<Integer> futureTask = new FutureTask<>(myThread);
new Thread(futureTask,"A").start();
Integer integer = futureTask.get();//get方法有可能会产生阻塞
System.out.println(integer);
}
}
class MyThread implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("call");
return 1024;
}
}