Callable与Future的作用:程序启动一个线程,线程运行完以后有一个返回结果,它可以获得线程运行完之后的返回结果,通过代码看看效果。
- 1-1 一个Callable与Future的例子
- import java.util.*;
- import java.util.concurrent.*;
- public class CallableAndFuture {
- public static void main(String[] args) {
- ExecutorService threadPool= Executors.newSingleThreadExecutor();//单线程
- Future<String> future=//submit提交返回的结果,类型是Callable返回的类型
- threadPool.submit(//提交一个任务
- new Callable<String>() {
- public String call() throws Exception {
- Thread.sleep(2000);
- return "hello";//返回的类型是String
- };
- }
- );
- System.out.println("等待结果");
- try {
- System.out.println("拿到结果"+future.get());//future.get()获取返回的结果
- //回来看一下看是否有结果,没有的话抛出异常(线程去干别的事了,而不用一直等待结果)
- //System.out.println("拿到结果"+future.get(1,TimeUnit.SECONDS));
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (ExecutionException e) {
- e.printStackTrace();
- }
- /* CompletionService<V>用于提交一组Callable任务,其take方法返回已完成的一个
- Callable任务对应的Future对象,好比我同是种了几块地麦子,然后就等待收割,收割
- 时,则是那块先成熟了,先去收割那块麦子,而不是哪一块先种,先去收个哪一块。
- */
- ExecutorService threadPool2= Executors.newFixedThreadPool(10);//newFixedThreadPool(10)固定大小的线程池,10个
- //CompletionService<V>是一个接口,应该New它的子类
- //将线程池传递进去执行它的任务
- CompletionService<Integer> completionService=new ExecutorCompletionService<Integer>(threadPool2);
- for (int i = 1; i <= 10; i++) {//提交10任务
- final int seq=i;//任务的序号
- completionService.submit(new Callable<Integer>() {//submit()提交任务
- @Override
- public Integer call() throws Exception {
- Thread.sleep(new Random().nextInt(5000));//每隔任务不超过5秒
- return seq;//返回任务的序号
- }
- });
- }
- //等待收获completionService返回的结果
- for (int i = 0; i < 10; i++) {//10个任务,需要拿10遍
- try {
- System.out.println(
- completionService.take().get());//打印返回的结果
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (ExecutionException e) {
- e.printStackTrace();
- }
- }
- }
- }
程序运行的结果:
从以上运行结果可以看出,返回了提交的10的任务的编号。上述代码的整体执行思路:产生线程————向线程提交任务————任务运行完之后,返回任务的结果————获取任务的结果。