多线程FutureTask执行流程
在Java中可以用来创建线程的方式很多,比如由Java提供的Thread、Runnable等。本文章来介绍使用FutureTask创建线程,以及其流程。Thread和Runnable的问题
众所周知,使用Thread、Runnable创建线程是非常方便的,只要实现线程的run方法即可。但是通过Thread、Runnable实现run方法创建的线程是无法获取返回结果的,原因是线程方法run本身是没有返回值的。但是在很多场景中,我们是需要异步执行的同时获取其线程执行的返回结果的。因此Java除了Thread、Runnable外,还提供了FutureTask,它使得我们可以在异步执行的同时获取到线程的返回结果。
本文就来介绍一下FutureTask类的简单使用。FutureTask介绍
FutureTask类本身不能用来创建线程,创建线程的工作仍然是由Thread类来创建的,FutureTask和Runnable类似,是通过Thread类的构造方法传递给Thread类的。但是注意观察,Thread类并没有一个构造方法是用于接受FutureTask类型的构造方法。FutureTask定义与继承关系
那么,FutureTask为什么可以传递给Thread类呢?这里重点不是看Thread类的构造方法,而是应该看一下FutureTask类的定义,该类的定义如下:publicclassFutureTaskVimplementsRunnableFutureV{
可以看到,FutureTask实现了RunnableFuture接口,那么继续看RunnableFuture接口的定义,该定义如下:publicinterfaceRunnableFutureVextendsRunnable,FutureV{voidrun();}
从RunnableFuture接口的定义可以看出,它继承了Runnable接口,那么这样,就可以将FutureTask类以构造方法参数的形式传递给Thread类了。在RunnableFuture接口中有一个run方法,那么这就要求实现RunnableFuture接口的类要去实现了run()方法。这样,FutureTask类既然实现了RunnableFuture接口,那么FutureTask类中必然有一个run方法是供Thread类调用的。
那么RunnableFuture继承的Future是什么呢?看一下它的定义,定义如下:publicinterfaceFutureV{booleancancel(booleanmayInterruptIfRunning);booleanisCancelled();booleanisDone();Vget()throwsInterruptedException,ExecutionException;Vget(longtimeout,TimeUnitunit)throwsInterruptedException,ExecutionException,TimeoutException;}
Future是一个泛型接口,通过get()方法可以阻塞等待获取异步计算的结果,也可以在获取异步计算结果的阻塞上设置一个超时时间。还可以通过cancel()方法设置让线程取消、使用isCancelled()方法判断线程是否被取消、以及通过isDone()方法判断线程是否执行完成。
同样的,Future接口中的所有实现均在FutureTask中可以找到。
总结一下,FutureTask实现了Runnable接口的run()方法(该方法在Thread。start()后被调用),实现了Future的get()、cancel()、isCancelled()和isDone()方法。但是,get()方法是从何处获取到线程的结果呢?这次来看一下FutureTask的run()方法吧。FutureTask实现的run方法分析
FutureTask实现了RunnableFuture接口,RunnableFuture继承了Runnable接口,那么FutureTask则可以作为Thread类的构造方法的参数传递给Thread类,FutureTask类实现的run方法的代码如下:publicvoidrun(){if(state!NEW!UNSAFE。compareAndSwapObject(this,runnerOffset,null,Thread。currentThread()))return;try{CallableVccallable;if(c!nullstateNEW){Vresult;booleanran;try{resultc。call();rantrue;}catch(Throwableex){resultnull;ranfalse;setException(ex);}if(ran)set(result);}}finally{runnermustbenonnulluntilstateissettledtopreventconcurrentcallstorun()runnernull;statemustberereadafternullingrunnertopreventleakedinterruptsintsstate;if(sINTERRUPTING)handlePossibleCancellationInterrupt(s);}}
从上面的代码中可以看出,FutureTask的run()方法是固定的,并不能在该run方法中实现我们自己的业务代码,那应该如何完成自己的线程业务代码呢?来观察一下上面的代码。
上面的代码中,主要看try块中的代码,在第7行,定义了一个Callable的变量c,在第9行,定义了一个泛型的result变量,在第12行,有一句resultc。call(),在第20行有一句set(result)。我们分别来观察一下这基础。
第7行代码如下:CallableVccallable;
第7行代码中的callable是FutureTask的属性,其定义如下:privateCallableVcallable;
它是通过构造方法赋值得到的,FutureTask的构造方法如下:publicFutureTask(CallableVcallable){if(callablenull)thrownewNullPointerException();this。callablecallable;this。stateNEW;ensurevisibilityofcallable}
那么,我们在使用FutureTask时,会给它传递Callable来实例化它。接着看第12行代码,代码如下:resultc。call()
可以看出,Callable有一个call()方法,并且有返回值,那么来看一下Callable的定义,它的定义如下:FunctionalInterfacepublicinterfaceCallableV{Vcall()throwsException;}
可以看到它是一个泛型接口,该接口中有一个方法call(),它有返回值,且可以抛出异常。而这个call()方法,就是我们用来写自己业务的线程方法。然后这个方法在FutureTask的run()方法中被调用。那么返回值呢?同样从第12行代码可以看出,c。call()后把返回值给到了result中,最后调用了第20行的代码,代码如下:set(result)
我们来查看set()方法做了什么,代码如下:protectedvoidset(Vv){if(UNSAFE。compareAndSwapInt(this,stateOffset,NEW,COMPLETING)){outcomev;UNSAFE。putOrderedInt(this,stateOffset,NORMAL);finalstatefinishCompletion();}}
set()方法将返回值赋值给了outcome,outcome也是FutureTask的属性,其定义如下:privateObjectoutcome;
前面介绍过,get()方法是用来获取返回结果的,我们通过观察get()方法来验证一下,代码如下:SuppressWarnings(unchecked)privateVreport(ints)throwsExecutionException{Objectxoutcome;if(sNORMAL)return(V)x;if(sCANCELLED)thrownewCancellationException();thrownewExecutionException((Throwable)x);}publicVget()throwsInterruptedException,ExecutionException{intsstate;if(sCOMPLETING)sawaitDone(false,0L);returnreport(s);}
可以看到,get()方法返回的就是实际的outcome这个属性。FutureTask实例
来一个简单的例子,来看看FutureTask的使用,代码如下:publicclassFutureTaskTest{staticpublicclassCallableThreadimplementsCallableInteger{此处的call方法是实际的线程方法,写我们的异步任务这里是一个简单的计算100的累加和OverridepublicIntegercall()throwsException{intsum0;for(inti1;i100;i){sumi;}returnsum;}}publicstaticvoidmain(String〔〕args){CallableThreadcallableThreadnewCallableThread();FutureTaskIntegerintegerFutureTasknewFutureTask(callableThread);ThreadthreadnewThread(integerFutureTask);thread。start();try{这里通过FutureTask。get()方法来阻塞获取结算的结果System。out。println(integerFutureTask。get());}catch(InterruptedExceptionExecutionExceptione){e。printStackTrace();}}}
上面的示例代码非常的简单,在线程任务中完成一个100内的累加和计算,然后在main线程中通过FutureTask的get()方法来阻塞的获取计算结果。总结
总结一下,使用FutureTask类时,要配合使用Thread类和Callable接口,刚开始看可能对三个类之间的关系有点乱,但是当实际的了解了FutureTask类的run()方法以后,其实整个脉络就清楚了。与FutureTask类相关的几个重要接口有RunnableFuture、Runnable、Future,以及Callable。能清楚的梳理好它们之间的关系,就可以相对清楚的明白FutureTask类了。
希望本文对你有所帮助!喜欢可以点赞、分享!
雨说四年级学生作文500字倚在窗边,雨不住地下着。视线渐渐朦胧,只是听到雨降临这世界的声响。水池里,唰唰唰;瓦檐上,滴滴滴。雨,它一定在诉说着什么,什么呢?漆黑的巷尾里,一个断了腿的乞丐艰难的在挪动。雨……
阿里巴巴再爆性侵女同事丑闻!网友不满企业处理结果价值观崩了据环球网报道,本月7日,一名阿里女员工在社交媒体上发布了一篇8000字长文,自述受到领导性侵却投诉无门,帖子被微博认证为一篇网络创始人赵宏明的大V博主截图转发,且配文受害者向公……
精选母爱的小学生作文500字锦集七篇在学习、工作乃至生活中,大家都不可避免地会接触到作文吧,写作文可以锻炼我们的独处习惯,让自己的心静下来,思考自己未来的方向。那么一般作文是怎么写的呢?下面是小编精心整理的母爱的……
关国庆节日记400字作文关国庆节日记400字作文由日记栏目为大家整合而成,有兴趣的朋友不妨参考一下,希望对你们有帮助!ldquo;跟屁虫rdquo;每一年十月的第一天都是我们中华民族的生日……
精品愚人节作文400字集合5篇在平平淡淡的学习、工作、生活中,大家都跟作文打过交道吧,通过作文可以把我们那些零零散散的思想,聚集在一块。你写作文时总是无从下笔?下面是小编帮大家整理的愚人节作文400字5篇,……
经阿里女员工事件后,当代人能否终结酒桌文化近日,阿里女员工疑遭侵害事件引起了舆论爆炸。酒桌文化作为该事件的舆情焦点之一,引起了网友的广泛讨论并在网上不断发酵中。酒桌文化餐饮礼仪的一种,据文献记载可知,至少在……
时代广场的蟋蟀国际大奖小说(一)时代广场的的蟋蟀(瑛荞连载经典小说)自由和功成名就,你选哪个?题记第一章塔克一只老鼠正望着玛丽欧。老鼠的名字叫塔克,此时他正坐在纽约最繁华的地方时……
描写老师的好词好句(祝愿篇)敬爱的老师,您的谆谆教诲如春风,似瑞雨,永铭我心。我虔诚地祝福您:康乐、如意!我们从幼苗长成大树,却永远是您的学生。在您花甲之年,祝您生命之树常青。您因材施教,善启……
荣耀Magic3系列影像功能曝光,加入电影制作流程作为荣耀方面即将于8月12日推出的新款旗舰机型,随着Magic3系列亮相时间的临近,其大量产品端的相关信息也已经陆续被曝光,并吸引了外界的众多关注。继此前官方公布了Magic3……
美的空调和格力空调哪个品牌质量好一点?我邻居同一栋楼的有三家装的美的中央空调,其中两台在7月最热的那段时间不制冷或制冷效果不佳,且原因不明,我自己家里的美的电饭煲,电饼铛,用一段时间后涂层开始脱落,对美的已无信心……
小学记事作文生活中的发现500字篇一:生活中的发现我在生活中经常发现一些有趣的现象,今天举几个例子和大家分享一下:妈妈给我买了插卡式音响(MP3)并下载了大量的音频资料:有音乐,也有童话、名著、历……
OPPO水下超声波定位曝光,未来手机或许可以潜水?众所周知,作为国内一线品牌厂商而言,OPPO一直都是科技创新方面的行家,而且它的创新一般都是十分超前的,引领着行业的发展潮流。比如近段时间OPPO公开的水下超声波定位专利,或许……
崂山游记初中作文多少次我在网上看过崂山,它是那么壮观,多少次我听同学们说起崂山樱桃多么汁多味美。今年夏天,我终于和爸爸妈妈一起去崂山摘了樱桃。一路上,我跟妈妈兴奋地讨论着。我问妈妈:崂山……
阳光下的我们作文大全阳光下的我们作文大全1我的眼前突然起了一片雾,将我围住,而我就像个迷路的小孩,不知道出口在哪。题记这些分数一遍又一遍的在我的脑海里闪现,拨乱了我的思绪。……
阿里女员工性侵事件出现神反转?酒店再度确认房卡经女方同意办理阿里女员工被性侵事件可能出现反转,涉事的亚朵酒店再发声明,再次确认了被性侵女员工的领导(花名曲一,真名王成文)的房卡是经过涉事女员工同意后办理的,并且还确认了是按照同住手续办理……
反转还是脱罪!阿里女员工案涉事酒店发声明女方自愿阿里女员工案不止沸沸扬扬,甚至有点扑朔迷离,即阿里内部传出处理意见,济南华联超市发声明之后,本案两个重要事发地涉事饭店,以及涉事酒店先后推脱。先是涉事饭店以监控故障为由拒……
网友买国行iPhone翻车,验机全绿却是翻新机,为什么?网友总觉得自己的iPhone是翻新机,但又找不到证据,因为验机报告全绿,和关于本机也对得上。于是找到了我,让我帮忙看看iPhone是否有问题,以我多年的验机经验,一眼就发……
阿里女员工事件,网友扯出破冰文化到底是啥,属于哪家公司文化阿里女员工被性骚扰事件刚下热度,阿里做出回应,警方也介入调查,热度都快凉了,亚朵酒店又把热度给拉回来了,这些大家都吃瓜吃够了,那么有些网友扒出疑似阿里破冰文化截图,阿里也做出回……
那段红日岁月的日记范文在我姐的日记里有一段话,特别的有味道,我永远都忘不了那段记忆,那是青春最深的记忆,但是现在已经回不去了如今是网络时代的天下,往往会存在误会,这不明明看到有些人在线他却不回复,到……
二年级日记大全150字二年级日记:我学会了洗碗中午吃完饭了,我帮妈妈洗了一次碗。首先,我把吃过饭的碗和筷整理好,放进厨房。我打来一盆清水,放入一点点的洗洁精,拿来一块洗碗布,用洗碗布将碗……
荣耀发布一年多的中端5G还值得入手吗?90Hz麒麟820石墨荣耀自从与华为分家之后也是非常的艰难,不过市场份额经历黑暗之后也在逐渐回升,今天也正是发布了荣耀magic3系列,价格很高,荣耀也与性价比再无关系了,不过今天要说的这款手机是荣……
我的中国梦E度网专稿未经允许不得转载历史的点点滴滴如散落在偌大沙滩上的沙石贝壳,我悄悄走过,贪婪地看着这些晶莹宝贵的财富,时而拾起一两颗打动心灵的贝壳,寄出一份梦想,蹲下投放。中国……
小米电视6OLED来了,性价比爆表8月10日晚,2021雷军年度演讲暨小米秋季新品发布会正式举行,小米集团CEO雷军发表了主题为我的梦想,我的选择的年度演讲,与大家一起分享这十年小米发生了哪些变化,以及它是如何……
iOS15beta5新公测版推送,升级内容有这些在昨天推送了iOS15beta5开发者预览版之后,今天苹果向iPhone手机用户推送了iOS15beta5公测版升级更新,推送升级更新的版本号为19A5318f,想要升级的用户……