电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

詳解Java Callable接口實現多線程的方式

瀏覽:20日期:2022-09-02 15:09:45

在Java 1.5以前,創建線程的2種方式,一種是直接繼承Thread,另外一種就是實現Runnable接口。無論我們以怎樣的形式實現多線程,都需要調用Thread類中的start方法去向操作系統請求io,cup等資源。因為線程run方法沒有返回值,如果需要獲取執行結果,就必須通過共享變量或者使用線程通信的方式來達到效果,這樣使用起來就比較麻煩。

而自從Java 1.5開始,就提供了Callable和Future,通過它們可以在任務執行完畢之后得到任務執行結果。

Callable和Future介紹

Callable接口代表一段可以調用并返回結果的代碼;Future接口表示異步任務,是還沒有完成的任務給出的未來結果。所以說Callable用于產生結果,Future用于獲取結果。

Callable接口使用泛型去定義它的返回類型。Executors類提供了一些有用的方法在線程池中執行Callable內的任務。由于Callable任務是并行的(并行就是整體看上去是并行的,其實在某個時間點只有一個線程在執行),我們必須等待它返回的結果。java.util.concurrent.Future對象為我們解決了這個問題。在線程池提交Callable任務后返回了一個Future對象,使用它可以知道Callable任務的狀態和得到Callable返回的執行結果。Future提供了get()方法讓我們可以等待Callable結束并獲取它的執行結果。

Callable與Runnable

java.lang.Runnable吧,它是一個接口,在它里面只聲明了一個run()方法:

public interface Runnable { public abstract void run();}

由于run()方法返回值為void類型,所以在執行完任務之后無法返回任何結果。Callable位于java.util.concurrent包下,它也是一個接口,在它里面也只聲明了一個方法,只不過這個方法叫做call():

public interface Callable<V> { /** * Computes a result, or throws an exception if unable to do so. * @return computed result * @throws Exception if unable to compute a result */ V call() throws Exception;}

可以看到,這是一個泛型接口,call()函數返回的類型就是傳遞進來的V類型。

那么怎么使用Callable呢?

一般情況下是配合ExecutorService來使用的,在ExecutorService接口中聲明了若干個submit方法的重載版本:

<T> Future<T> submit(Callable<T> task);<T> Future<T> submit(Runnable task, T result);Future<?> submit(Runnable task);

Future

Future就是對于具體的Runnable或者Callable任務的執行結果進行取消、查詢是否完成、獲取結果。必要時可以通過get方法獲取執行結果,該方法會阻塞直到任務返回結果。

Future類位于java.util.concurrent包下,它是一個接口

:<T> Future<T> submit(Callable<T> task);<T> Future<T> submit(Runnable task, T result);Future<?> submit(Runnable task);

在Future接口中聲明了5個方法,下面依次解釋每個方法的作用:

cancel方法 用來取消任務,如果取消任務成功則返回true,如果取消任務失敗則返回false。參數mayInterruptIfRunning表示是否允許取消正在執行卻沒有執行完畢的任務,如果設置true,則表示可以取消正在執行過程中的任務。如果任務已經完成,則無論mayInterruptIfRunning為true還是false,此方法肯定返回false,即如果取消已經完成的任務會返回false;如果任務正在執行,若mayInterruptIfRunning設置為true,則返回true,若mayInterruptIfRunning設置為false,則返回false;如果任務還沒有執行,則無論mayInterruptIfRunning為true還是false,肯定返回true。

isCancelled方法 表示任務是否被取消成功,如果在任務正常完成前被取消成功,則返回 true。

isDone方法 表示任務是否已經完成,若任務完成,則返回true;

get()方法 用來獲取執行結果,這個方法會產生阻塞,會一直等到任務執行完畢才返回;

get(long timeout, TimeUnit unit) 用來獲取執行結果,如果在指定時間內,還沒獲取到結果,就直接返回null。

也就是說Future提供了三種功能: 

1)判斷任務是否完成;

2)能夠中斷任務;

3)能夠獲取任務執行結果。

Future用于表示異步計算的結果。它的實現類有java.util.concurrent.FutureTask<V>和 javax.swing.SwingWorker<T,V>,Android平臺上如果不想分支線程阻塞主線程,又想取得分支線程的執行結果,可以用FutureTask。

FutureTask

Java的類是單繼承的設計,如果采用繼承Thread的方式實現多線程,則不能繼承其他的類,采用接口能夠更好的實現數據共享

FutureTask實現了RunnableFuture接口,這個接口的定義如下:

public interface RunnableFuture<V> extends Runnable, Future<V> { void run(); }

可以看到這個接口實現了Runnable和Future接口,接口中的具體實現由FutureTask來實現。這個類的兩個構造方法如下 :

public FutureTask(Callable<V> callable) { if (callable == null) throw new NullPointerException(); sync = new Sync(callable); } public FutureTask(Runnable runnable, V result) { sync = new Sync(Executors.callable(runnable, result)); }

如上提供了兩個構造函數,一個以Callable為參數,另外一個以Runnable為參數。這些類之間的關聯對于任務建模的辦法非常靈活,允許你基于FutureTask的Runnable特性(因為它實現了Runnable接口),把任務寫成Callable,然后封裝進一個由執行者調度并在必要時可以取消的FutureTask。

FutureTask可以由執行者調度,這一點很關鍵。它對外提供的方法基本上就是Future和Runnable接口的組合:get()、cancel、isDone()、isCancelled()和run(),而run()方法通常都是由執行者調用,我們基本上不需要直接調用它。FutureTask類同時又實現了Runnable接口,所以可以直接提交給Thread、Executors執行:

public class CallableAndFuture { public static void main(String[] args) { Callable<Integer> callable = new Callable<Integer>() { public Integer call() throws Exception { return new Random().nextInt(100); } }; FutureTask<Integer> future = new FutureTask<Integer>(callable); new Thread(future).start(); try { Thread.sleep(5000);// 可能做一些事情int result = future.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }

public class CallableAndFuture { public static void main(String[] args) { //ExecutorService.submit() ExecutorService threadPool = Executors.newSingleThreadExecutor(); Future<Integer> future = threadPool.submit(new Callable<Integer>() { public Integer call() throws Exception { return new Random().nextInt(100); } }); try { Thread.sleep(5000);// 可能做一些事情int result = future.get()); //Future.get() } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }

如果要執行多個帶返回值的任務,并取得多個返回值,可用CompletionService:

CompletionService相當于Executor加上BlockingQueue,使用場景為當子線程并發了一系列的任務以后,主線程需要實時地取回子線程任務的返回值并同時順序地處理這些返回值,誰先返回就先處理誰。

public class CallableAndFuture { public static void main(String[] args) { ExecutorService threadPool = Executors.newCachedThreadPool(); CompletionService<Integer> cs = new ExecutorCompletionService<Integer>(threadPool); for(int i = 1; i < 5; i++) { final int taskID = i; //CompletionService.submit() cs.submit(new Callable<Integer>() { public Integer call() throws Exception { return taskID; } }); } // 可能做一些事情 for(int i = 1; i < 5; i++) { try { int result = cs.take().get()); //CompletionService.take()返回Future } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } } }

或者不使用CompletionService:先創建一個裝Future類型的集合,用Executor提交的任務返回值添加到集合中,最后便利集合取出數據。

區別:

Future集合方法,submit的task不一定是按照加入自己維護的list順序完成的。從list中遍歷的每個Future對象并不一定處于完成狀態,這時調用get()方法就會被阻塞住,如果系統是設計成每個線程完成后就能根據其結果繼續做后面的事,這樣對于處于list后面的但是先完成的線程就會增加了額外的等待時間。

而CompletionService的實現是維護一個保存Future對象的BlockingQueue。只有當這個Future對象狀態是結束的時候,才會加入到這個Queue中,take()方法其實就是Producer-Consumer中的Consumer。它會從Queue中取出Future對象,如果Queue是空的,就會阻塞在那里,直到有完成的Future對象加入到Queue中。

所以,先完成的必定先被取出。這樣就減少了不必要的等待時間。

到此這篇關于詳解Java Callable接口實現多線程的方式的文章就介紹到這了,更多相關Java Callable接口多線程內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Java
相關文章:
主站蜘蛛池模板: 工程管道/塑料管材/pvc排水管/ppr给水管/pe双壁波纹管等品牌管材批发厂家-河南洁尔康建材 | 欧美日韩国产一区二区三区不_久久久久国产精品无码不卡_亚洲欧洲美洲无码精品AV_精品一区美女视频_日韩黄色性爱一级视频_日本五十路人妻斩_国产99视频免费精品是看4_亚洲中文字幕无码一二三四区_国产小萍萍挤奶喷奶水_亚洲另类精品无码在线一区 | 工业设计,人工智能,体验式3D展示的智能技术交流服务平台-纳金网 J.S.Bach 圣巴赫_高端背景音乐系统_官网 | 微信聊天记录恢复_手机短信删除怎么恢复_通讯录恢复软件下载-快易数据恢复 | 安徽千住锡膏_安徽阿尔法锡膏锡条_安徽唯特偶锡膏_卡夫特胶水-芜湖荣亮电子科技有限公司 | 连续密炼机_双转子连续密炼机_连续式密炼机-南京永睿机械制造有限公司 | 在线悬浮物浓度计-多参数水质在线检测仪-上海沃懋仪表科技有限公司 | 电动手术床,医用护理床,led手术无影灯-曲阜明辉医疗设备有限公司 | 标策网-专注公司商业知识服务、助力企业发展 | 二手色谱仪器,十万分之一分析天平,蒸发光检测器,电位滴定仪-湖北捷岛科学仪器有限公司 | 皮带机_移动皮带机_大倾角皮带机_皮带机厂家 - 新乡市国盛机械设备有限公司 | 青海电动密集架_智能密集架_密集架价格-盛隆柜业青海档案密集架厂家 | 众品地板网-地板品牌招商_地板装修设计_地板门户的首选网络媒体。 | 招商帮-一站式网络营销服务|互联网整合营销|网络推广代运营|信息流推广|招商帮企业招商好帮手|搜索营销推广|短视视频营销推广 | 304不锈钢无缝管_不锈钢管厂家 - 隆达钢业集团有限公司 | NM-02立式吸污机_ZHCS-02软轴刷_二合一吸刷软轴刷-厦门地坤科技有限公司 | TTCMS自助建站_网站建设_自助建站_免费网站_免费建站_天天向上旗下品牌 | 溶氧传感器-pH传感器|哈美顿(hamilton)| 电缆接头-防爆电缆接头-格兰头-金属电缆接头-防爆填料函 | 数字展示在线_数字展示行业门户网站| 北京宣传片拍摄_产品宣传片拍摄_宣传片制作公司-现像传媒 | 紫外线老化试验箱_uv紫外线老化试验箱价格|型号|厂家-正航仪器设备 | 湖州织里童装_女童男童中大童装_款式多尺码全_织里儿童网【官网】-嘉兴嘉乐网络科技有限公司 | 沈阳楼承板_彩钢板_压型钢板厂家-辽宁中盛绿建钢品股份有限公司 轴承振动测量仪电箱-轴承测振动仪器-测试仪厂家-杭州居易电气 | 氢氧化钙设备_厂家-淄博工贸有限公司| 硫化罐_蒸汽硫化罐_大型硫化罐-山东鑫泰鑫智能装备有限公司 | 哔咔漫画网页版在线_下载入口访问指引 | 贝朗斯动力商城(BRCPOWER.COM) - 买叉车蓄电池上贝朗斯商城,价格更超值,品质有保障! | 无菌检查集菌仪,微生物限度仪器-苏州长留仪器百科 | 户外环保不锈钢垃圾桶_标识标牌制作_园林公园椅厂家_花箱定制-北京汇众环艺 | 硬度计_影像测量仪_维氏硬度计_佛山市精测计量仪器设备有限公司厂家 | 杭州代理记账多少钱-注册公司代办-公司注销流程及费用-杭州福道财务管理咨询有限公司 | 拉力机-拉力试验机-万能试验机-电子拉力机-拉伸试验机-剥离强度试验机-苏州皖仪实验仪器有限公司 | 碳化硅,氮化硅,冰晶石,绢云母,氟化铝,白刚玉,棕刚玉,石墨,铝粉,铁粉,金属硅粉,金属铝粉,氧化铝粉,硅微粉,蓝晶石,红柱石,莫来石,粉煤灰,三聚磷酸钠,六偏磷酸钠,硫酸镁-皓泉新材料 | 辽宁资质代办_辽宁建筑资质办理_辽宁建筑资质延期升级_辽宁中杭资质代办 | 集装箱标准养护室-集装箱移动式养护室-广州璟业试验仪器有限公司 | 欧美日韩国产一区二区三区不_久久久久国产精品无码不卡_亚洲欧洲美洲无码精品AV_精品一区美女视频_日韩黄色性爱一级视频_日本五十路人妻斩_国产99视频免费精品是看4_亚洲中文字幕无码一二三四区_国产小萍萍挤奶喷奶水_亚洲另类精品无码在线一区 | 风化石头制砂机_方解石制砂机_瓷砖石子制砂机_华盛铭厂家 | 「钾冰晶石」氟铝酸钾_冰晶石_氟铝酸钠「价格用途」-亚铝氟化物厂家 | 上海平衡机-单面卧式动平衡机-万向节动平衡机-圈带动平衡机厂家-上海申岢动平衡机制造有限公司 | 高扬程排污泵_隔膜泵_磁力泵_节能自吸离心水泵厂家-【上海博洋】 |