Future到底是什么东西?很多人都对这个东西感到特别奇怪(好吧,我承认,那个很多人就只是我自己而已),就我现在的理解,因为本人在并发这方面没有多少实践经验,所以只好就着一些资料和自己的理解给它下个定义,Future就是保存我们任务的完成信息,比如说,任务中会通过返回某些东西告诉别人它已经结束了,而Future中就保存了这种信息。利用Futu保存和得到任务的结果的用法如下:
Future<String> future = threadPool.submit(new Callable<String>(){ @Override public String call() throws Exception{ Thread.sleep(3000); return "future"; } try{ System.out.println("waiting....."); System.out.println(future.get()); }catch(InterruptedException e){ e.printStackTrace(); }catch(ExecutionException e){ e.printStackTrace(); }
注意到没?代码中的System.out.println(future.get())这一句,就是返回任务的结果,而任务的结果是保存在Future<String>中的,相信大家都有注意到,
Future<String> future = threadPool.submit(new Callable<String>(){ @Override public String call() throws Exception{} }
Callable相当于Runnable,所以,这里实现的是一个线程,但是与Runnable不同的是,它是具有返回值的,这个返回值就是我们想要任务返回的结果,比如说,我们想要任务返回的是一个提示信息,那么,返回值可以是String,然后在我们要实现的call()方法中return一句提示信息,接着只要使用Future类的get()方法,就可以从里面得到提示信息了,只要任务完成。所以,由此我们可以知道,java SE5比起以前来,在并发这方面做了更多的工作,它完善了我们的并发线程机制,使我们可以更好的根据任务的完成情况来进行与其他任务的协作,比如说,我们可以通过Future的返回值来决定是否终止任务,或者开启另一个任务。任务的终止可以使用Future的方法future.cancel(boolean),其中boolean为true或false,来决定是否终止,至于开启另一个任务,可以重新开启另一个线程,但是这里就马上有个问题浮现出来,就是当Futrue的结果返回来时,该任务有没有结束呢?因为这时一定已经执行完该任务的call()方法。是的,该任务已经结束了,只是我们没有取出它的返回结果而已。
看到上面,相信大家一定都对Future的新特性产生非常浓厚的兴趣,非常想要将这个新玩意儿马上运用起来,但是,且慢,每次在遇到这种新东西的时候,我们都会有一个念头,那就是我们有必要使用吗?如果旧的东西已经足够用了,那为什么还要用多余的方法呢?是的,这种想法是对的,因为我们的程序设计原则都是能够尽量简单则尽量简单,但是Future是一个接口,一个泛型接口,适合各种返回值的情况,而且这个接口提供了很多有用的方法,再加上,我们永远无法知道我们的代码以后到底会变成怎么样子,是否需要添加新的功能等等,而这些,如果一开始使用的是旧的东西的话,添加新的东西,那么,我们就要对我们的代码进行修改,但是,我是这么认为的,就目前而言,Thread修改为Future并不是很难,所以,这方面倒是没有多大顾虑,熟悉啥就用啥,至少都要了解,因为我们在写代码时,更多时间里是在阅读别人的代码,如果别人使用的代码是使用以前的接口的话,而且这种情况是非常常见的,所以,我们必须要看得懂代码并且能够将其转化为我们的新接口,这些就需要我们能够对其有一定的了解,并且明白它们之间的联系和区别。所以,接下来就是介绍一下新接口的一些方法以便我们能够更好的使用新接口。
ExecutorService executor = Executors.newSingleThreadExecutor(); FutureTask<String> future = new FutureTask<String>(new Callable<String>() {//使用Callable接口作为构造参数 public String call() { //真正的任务在这里执行,这里的返回值类型为String,可以为任意类型 }}); executor.execute(future); //在这里可以做别的任何事情 try { result = future.get(5000, TimeUnit.MILLISECONDS); //取得结果,同时设置超时执行时间为5秒。同样可以用future.get(),不设置执行超时时间取得结果 } catch (InterruptedException e) { futureTask.cancel(true); } catch (ExecutionException e) { futureTask.cancel(true); } catch (TimeoutException e) { futureTask.cancel(true); } finally { executor.shutdown(); }
这里就是FutureTask的一般用法,它最大的好处就是我们可以将任务交给执行器后执行其他操作,然后再从里面得到任务的结果。这里必须要注意,只有FutureTask这种既实现Runnable又实现Callable才能够通过executor()递交给ExecutorService,而Future不行,只能通过submit(),因为executor()要求的参数是一个实现了Runnable的类。如果我们不想要直接构造Future对象,那么我们可以这样写:
ExecutorService executor = Executors.newSingleThreadExecutor(); FutureTask<String> future = executor.submit( new Callable<String>() {//使用Callable接口作为构造参数 public String call() { //真正的任务在这里执行,这里的返回值类型为String,可以为任意类型 }}); //在这里可以做别的任何事情 //同上面取得结果的代码
这里是使用ExecutorService.submit方法来获得Future对象,submit方法既支持Callable接口类型,也支持Runnable接口作为参数,具有很大的灵活性,而且所有的submit()方法都会返回一个Future值,无论是Runnable还是Callable。上面两种方法哪种比较好?其实都一样,只是第二种的话,可以在定义FutureTask的同时就将FutureTask提交给Executor。个人的话,比较倾向于第二种,因为我们的代码如果在不影响阅读性的基础上能够越简单越好,哪怕是一句代码。
for (;;) { schedule = getNextScheduledTaskTime(); while(schedule > now()) { try { data = subscription.waitNext(schedule - now()); processData(data); } catch(Exception e) {...} } doScheduledTask(); }
相关推荐
\n\n随着技术的进步,Flash逐渐发展出多个版本,从最初的Future Splash Animator到Flash 1.0,再到Flash 5.0,每个版本都带来了新的功能和改进。尤其是ActionScript的进化,让Flash的编程能力得到了显著提升,使其...
"浅谈Java多线程处理中Future的妙用" 在Java多线程处理中,Future是一个非常重要的概念,它可以帮助我们更好地处理并发任务。Future是一个未来对象,里面保存着线程处理结果,它像一个提货凭证,拿着它你可以随时去...
从Java 1.5开始,引入了Callable和Future接口,为并行编程提供了一种更为高效和便捷的解决方案。 Callable接口是Java并发库中的一个关键接口,位于`java.util.concurrent`包下。Callable接口与Runnable接口类似,但...
浅谈CPU技术的发展.pdf 在计算机发展的五十年中,CPU(Central Processing Unit,中央处理器)技术的发展经历了多个阶段。从早期的4位CPU到具有MMX技术的Pentium时代,CPU技术的发展对于计算机性能的提高起到了关键...
《Rust异步和并发浅谈》的主题演讲深入探讨了Rust编程语言在处理异步和并发场景中的机制。Rust是由Onchain的区块链架构师赖智超在Rust China Conf 2020上分享的,展示了Rust在公司项目中的应用,包括区块链Wasm JIT...
"浅谈未来计算机操作系统的发展方向" 随着科学技术的不断发展与创新,计算机操作系统作为计算机系统的基础正在不断发展和完善。操作系统作为管理计算机软硬件资源、控制程序运行、改善人机界面和为应用软件提供支持...
Future trends include technological innovation, interactivity, creativity, better integration with the environment, targeting specific audiences, market dominance, improved regulation, and ongoing ...
Future<?> future = executor.submit(new Runnable() { public void run() { // 任务代码 } }); ``` 4. synchronized关键字:用于同步控制,保证多线程环境下对共享资源的访问有序性。它可以修饰方法或代码块,...
例如,Herry Blodget的《The Future Of Mobile》以及Karl E. Wiegers的著作,都可能为系统开发提供理论依据和实践指导。参考文献中提供的数据、分析和案例研究等,可以帮助开发者更好地理解移动互联网技术的发展趋势...
为了保持句子的平衡,有时会使用“it”作为形式主语,而真正的主语不定式则放在句尾,如:“It is difficult for Marty Fielding to know what the future holds.” 在这里,“for Marty Fielding to know”是真正...
4. Challenges and Future DirectionsDespite the advantages, there are still challenges in integrating electronic diagnostic technology into new energy vehicle maintenance. These include the high cost ...
浅谈Android中多线程切换的几种方法 本篇文章主要介绍了Android中多线程切换的几种方法,包括Thread、ThreadPool、Runnable、Callable、Future、Condition、Handler等方法。多线程切换是Android开发中必现的场景,...
浅谈Spring @Async异步线程池用法总结 本文主要介绍了Spring @Async异步线程池的用法总结,包括异步线程池的接口类、@Async定义异步任务、Spring开启异步配置等内容。 1. 异步线程池的接口类 Spring提供了多种...
"浅谈Java内存模型之happens-before" Java内存模型是Java虚拟机中的一种机制,用于定义Java程序中线程之间的内存访问方式。在多线程环境下,线程之间的通信和数据共享是非常复杂的,需要有一些规则来保证数据的一致...
`FutureTask`是`Executor`框架的一部分,它代表一个异步计算的结果,可以通过`Callable`接口实现,其`Future.get()`方法可以等待任务完成并获取结果。 同步器,如`Semaphore`(信号量)、`CyclicBarrier`(屏障/关卡)...
import java.util.concurrent.Future; import java.util.concurrent.RecursiveTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /* Created by hujian06 on 2017/9/28....
from __future__ import absolute_import python2缺省会搜索上一级目录、上上级目录 解决方案: import platform pver=platform.python_version() pversion= int(pver.split('.')[0]) try: if pversion==2: print...
3. **使用Future和Timeout**:如代码示例所示,可以利用`Future.get()`方法的超时参数,当线程执行超过设定时间时,可以选择抛出异常或者返回默认值,而不是阻塞其他线程。 4. **线程同步与通信**:使用`...
from __future__ import unicode_literals from django.db import models # Create your models here. # 一对一关系:数据库中两个表中数据的对应关系 # 一个账户对应着一个联系人,而一个联系人有一个账户 # 一对一...