Future和Callable是多线程中常见的两个类,在Java并发编程实战中有多次提及,写了一个demo演示一下
类的作用
- Callable
了解线程肯定知道Thread这个线程类,但是一般实现自定义的线程的时候都是实现Runnable这个接口,重写抽象方法run()的。但是这个run()方法是没有返回值的,有的时候我们需要做异步操作,而且需要得到这个操作的返回值,这个时候Callable的价值就出来了。看名字就知道,可回调的。实现它的抽象方法call(),这个是可以带返回值的。
- Future
执行Callable实现类,我们用线程池,这样提高效率并且减少资源开销。ExecutorService的对象调用submit(Callable c)方法返回的值就是Future。这里的T就是返回值的类型。
代码演示
public class FutureDemo {
public static void main(String[] args) {
//创建一个线程池
ExecutorService executor = Executors.newCachedThreadPool();
Task task = new Task();
//线程池去维护这个异步线程操作
Future<Integer> result = executor.submit(task);
executor.shutdown();
try {
//主线程sleep 1秒
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("主线程在执行任务");
try {
//这里其实会一直阻塞,直到异步线程将我们需要的结果返回出来再打印。
//所以这里会抛出阻塞异常
System.out.println("task运行结果"+result.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//主线程是守护线程,等到上面的异步线程都执行完成了,那么就是打印则最后一句话然后退出
System.out.println("所有任务执行完毕");
}
}
/**
* 实现类
*/
class Task implements Callable<Integer>{
@Override
public Integer call() throws Exception {
System.out.println("子线程在进行计算");
Thread.sleep(3000);
int sum = 0;
for(int i=0;i<100;i++)
sum += i;
return sum;
}
}