FutureTask详解

简介: 本章讲解了FutureTask的用法和使用场景

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;
        }
@OverridepublicIntegercall() 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
相关文章
|
3月前
|
Java API 调度
JUC线程池: FutureTask详解
总而言之,FutureTask是Java并发编程中一个非常实用的类,它在异步任务执行及结果处理方面提供了优雅的解决方案。在实现细节方面可以搭配线程池的使用,以及与Callable接口的配合使用,来完成高效的并发任务执行和结果处理。
44 0
|
4月前
|
存储 缓存 安全
(八)深入并发之Runnable、Callable、FutureTask及CompletableFuture原理分析
关于Runnable、Callable接口大家可能在最开始学习Java多线程编程时,都曾学习过一个概念:在Java中创建多线程的方式有三种:继承Thread类、实现Runnable接口以及实现Callable接口。但是实则不然,真正创建多线程的方式只有一种:继承Thread类,因为只有`new Thread().start()`这种方式才能真正的映射一条OS的内核线程执行,而关于实现Runnable接口以及实现Callable接口创建出的Runnable、Callable对象在我看来只能姑且被称为“多线程任务”,因为无论是Runnable对象还是Callable对象,最终执行都要交由Threa
|
6月前
|
Java API
java多线程之FutureTask、Future、CompletableFuture
java多线程之FutureTask、Future、CompletableFuture
266 0
JavaThread、Runnable、Callable、线程池的使用
JavaThread、Runnable、Callable、线程池的使用
JavaThread、Runnable、Callable、线程池的使用
|
Java
深入理解FutureTask
我们在日常的多线程编程中,为了充分的利用现在计算机多核的CPU资源,通常是需要开启多个线程来执行相对应的异步任务。在Java中,如果想新建一个线程,就必须要实现Runnable接口或者继承Thread。但是无论这两种方式如何实现,我们都无法获取任务执行的返回结果,那么有没有一种方式是可以获取异步线程返回的结果呢?
809 2
深入理解FutureTask
|
Java
Java多线程 Future和FutureTask的区别
Java多线程 Future和FutureTask的区别
186 0
Java多线程 Future和FutureTask的区别
|
存储
多线程 - Callable、Future 和 FutureTask 简单应用(二)
多线程 - Callable、Future 和 FutureTask 简单应用(二)
119 0
多线程 - Callable、Future 和 FutureTask 简单应用(二)
FutureTask详解
FutureTask详解
400 0
FutureTask详解
|
消息中间件 Dubbo Java
“既生 ExecutorService, 何生 CompletionService?”
“既生 ExecutorService, 何生 CompletionService?”
“既生 ExecutorService, 何生 CompletionService?”