FutureTask的用法
FutureTask可用于异步获取执行结果或取消执行任务的场景。经过传入Runnable或者Callable的任务给FutureTask,直接调用其run方法或者放入线程池执行,以后能够在外部经过FutureTask的get方法异步获取执行结果,所以,FutureTask很是适合用于耗时的计算,主线程能够在完成本身的任务后,再去获取结果。另外,FutureTask还能够确保即便调用了屡次run方法,它都只会执行一次Runnable或者Callable任务,或者经过cancel取消FutureTask的执行等。
执行多任务计算
FutureTask执行多任务计算的使用场景安全
利用FutureTask和ExecutorService,能够用多线程的方式提交计算任务,主线程继续执行其余任务,当主线程须要子线程的计算结果时,在异步获取子线程的执行结果。
代码实现
packageorg.example; importjava.util.ArrayList; importjava.util.List; importjava.util.concurrent.*; publicclassFutureTaskForMultiCompute { publicstaticvoidmain(String[] args) { FutureTaskForMultiComputeinst=newFutureTaskForMultiCompute(); // 建立任务集合List<FutureTask<Integer>>taskList=newArrayList<FutureTask<Integer>>(); // 建立线程池ExecutorServiceexec=Executors.newFixedThreadPool(5); for (inti=0; i<10; i++) { // 传入Callable对象建立FutureTask对象FutureTask<Integer>ft=newFutureTask<Integer>(inst.newComputeTask(i, ""+i)); taskList.add(ft); // 提交给线程池执行任务,也能够经过exec.invokeAll(taskList)一次性提交全部任务;exec.submit(ft); } System.out.println("全部计算任务提交完毕, 主线程接着干其余事情!"); // 开始统计各计算线程计算结果IntegertotalResult=0; for (FutureTask<Integer>ft : taskList) { try { //FutureTask的get方法会自动阻塞,直到获取计算结果为止totalResult=totalResult+ft.get(); } catch (InterruptedExceptione) { e.printStackTrace(); } catch (ExecutionExceptione) { e.printStackTrace(); } } // 关闭线程池exec.shutdown(); System.out.println("多任务计算后的总结果是:"+totalResult); } privateclassComputeTaskimplementsCallable<Integer> { privateIntegerresult=0; privateStringtaskName=""; publicComputeTask(IntegeriniResult, StringtaskName) { result=iniResult; this.taskName=taskName; System.out.println("生成子线程计算任务: "+taskName); } publicStringgetTaskName() { returnthis.taskName; } publicIntegercall() throwsException { for (inti=0; i<100; i++) { result=i; } // 休眠5秒钟,观察主线程行为,预期的结果是主线程会继续执行,到要取得FutureTask的结果是等待直至完成。Thread.sleep(5000); System.out.println("子线程计算任务: "+taskName+" 执行完成!"); returnresult; } } }
打印结果
生成子线程计算任务: 0生成子线程计算任务: 1生成子线程计算任务: 2生成子线程计算任务: 3生成子线程计算任务: 4生成子线程计算任务: 5生成子线程计算任务: 6生成子线程计算任务: 7生成子线程计算任务: 8生成子线程计算任务: 9全部计算任务提交完毕, 主线程接着干其余事情!子线程计算任务: 3执行完成!子线程计算任务: 2执行完成!子线程计算任务: 0执行完成!子线程计算任务: 4执行完成!子线程计算任务: 1执行完成!子线程计算任务: 7执行完成!子线程计算任务: 8执行完成!子线程计算任务: 6执行完成!子线程计算任务: 9执行完成!子线程计算任务: 5执行完成!多任务计算后的总结果是:990Processfinishedwithexitcode0