成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

(十八)java多線程之Callable Future

stormgens / 2971人閱讀

摘要:本人郵箱歡迎轉(zhuǎn)載轉(zhuǎn)載請(qǐng)注明網(wǎng)址代碼已經(jīng)全部托管有需要的同學(xué)自行下載引言前面我們講了那么多有關(guān)線程的知識(shí)不知道讀者有沒(méi)有想過(guò)這么一個(gè)問(wèn)題如果有這么一個(gè)比較耗時(shí)的任務(wù)必須使用線程來(lái)執(zhí)行但是在這個(gè)任務(wù)執(zhí)行完之后我需要得到這個(gè)線程的返回值以目前我們

本人郵箱:
歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明網(wǎng)址 http://blog.csdn.net/tianshi_kco
github: https://github.com/kco1989/kco
代碼已經(jīng)全部托管github有需要的同學(xué)自行下載

引言

前面我們講了那么多有關(guān)線程的知識(shí).不知道讀者有沒(méi)有想過(guò)這么一個(gè)問(wèn)題,如果有這么一個(gè)比較耗時(shí)的任務(wù),必須使用線程來(lái)執(zhí)行,但是在這個(gè)任務(wù)執(zhí)行完之后,我需要得到這個(gè)線程的返回值.以目前我們學(xué)到的知識(shí),具體實(shí)現(xiàn),我這里不說(shuō),大家自行發(fā)揮.除此之外,如果線程發(fā)生了非運(yùn)行時(shí)異常,我們?cè)谥骶€程就會(huì)收到一堆錯(cuò)誤信息.還有我們也無(wú)法判斷任務(wù)是否執(zhí)行完成,有些人會(huì)說(shuō)用Thread1.isAlive()就可以判斷任務(wù)是否執(zhí)行完成.這是錯(cuò)的,因?yàn)?b>isAlive只是判斷線程是否存活,而無(wú)法判斷任務(wù)是否完成,兩者是不一樣的概念.如果有沒(méi)有不明白的,請(qǐng)考慮使用線程池ThreadPoolExecutor的情況.
以上說(shuō)了那么多,其實(shí)就是為了引入今天要講的Callable,Future,FutureTask.ok,讓我們看一下這些類是干什么的.

理論

*Callable 可以說(shuō)是 Runnable的升級(jí)版本,既有拋出錯(cuò)誤也有返回類型.
*Future 是執(zhí)行異步任務(wù)后的返回值,這個(gè)接口包括一下幾個(gè)方法

* `cancel(boolean mayInterruptIfRunning)` 取消任務(wù),如果`mayInterruptIfRunning`為`true`,即使該任務(wù)在運(yùn)行也可以被中斷.否則在運(yùn)行中的任務(wù)不能被取消.
* `isCancelled`判斷任務(wù)是否被取消
* `isDone` 判斷任務(wù)是否完成
* `get` 獲取任務(wù)的返回值,如果任務(wù)有異常,則在調(diào)用這個(gè)方法的時(shí)候被拋出
* `get(long timeout, TimeUnit unit)` 在指定時(shí)間內(nèi)等待獲取任務(wù)的返回值,如果任務(wù)有異常,則在調(diào)用這個(gè)方法的時(shí)候被拋出

FutureTaskRunnableFuture的子類

例子1 獲取異步任務(wù)的返回值 Runnable 版本
public class Demo1 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main start");
        FutureTask task = new FutureTask(() -> System.out.println("執(zhí)行子任務(wù)"), "hello");
        new Thread(task).start();
        while (task.isDone());
        System.out.println("任務(wù)返回結(jié)果:" + task.get());
        System.out.println("main end");
    }
}

運(yùn)行結(jié)果

main start
執(zhí)行子任務(wù)
任務(wù)返回結(jié)果:hello
main end

public FutureTask(Runnable runnable, V result) 這個(gè)比較適合固定任務(wù)返回固定值的情況,如果返回的值需要進(jìn)過(guò)計(jì)算,所以有多個(gè)情況,則不適合使用這個(gè)構(gòu)造.

例子1 獲取異步任務(wù)的返回值 Callable 版本
public class Demo2 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main start");
        FutureTask task = new FutureTask(() -> {
            int sum = 0;
            for (int i = 1; i <= 100; i++){
                sum += i;
            }
            return sum;
        });
        new Thread(task).start();
        while (task.isDone());
        System.out.println("任務(wù)返回結(jié)果:" + task.get());
        System.out.println("main end");
    }
}

返回結(jié)果

main start
任務(wù)返回結(jié)果:5050
main end

例子3 測(cè)試運(yùn)行時(shí)異常情況
public class Demo3 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main start");
        FutureTask task = new FutureTask(() -> {
            System.out.println("正在執(zhí)行子任務(wù)");
            int i = 1 / 0;
            return 0;
        });
        new Thread(task).start();
        while (task.isDone());
        System.out.println("任務(wù)返回結(jié)果:" + task.get());
        System.out.println("main end");
    }
}

運(yùn)行結(jié)果:

main start
正在執(zhí)行子任務(wù)
Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at com.kco.test18.demo.Demo3.main(Demo3.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.ArithmeticException: / by zero
at com.kco.test18.demo.Demo3.lambda$main$0(Demo3.java:14)
at com.kco.test18.demo.Demo3$$Lambda$1/27095111.call(Unknown Source)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.lang.Thread.run(Thread.java:745)

需要注意的是,這是拋出的異常是在調(diào)用task.get()才拋出的,如果把task.get()注釋掉,是不會(huì)拋出異常的.所以我們就可以對(duì)異常做一下自定義處理.比如寫(xiě)到日志中.

例子4 取消正在執(zhí)行的任務(wù)
public class Demo4 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main start");
        FutureTask task = new FutureTask(() -> {
            System.out.println("start 正在執(zhí)行子任務(wù)");
            Thread.sleep(500);
            System.out.println("end 執(zhí)行子任務(wù)");
            return 0;
        });
        new Thread(task).start();
        Thread.sleep(250);
        task.cancel(true);
        System.out.println("main end");
    }
}

運(yùn)行結(jié)果

main start
start 正在執(zhí)行子任務(wù)
main end

發(fā)現(xiàn)子任務(wù)確實(shí)運(yùn)行運(yùn)行了一般,然后被取消了.

補(bǔ)充

上一篇講到了ThreadPoolExecutor,我們?cè)趫?zhí)行任務(wù)的時(shí)候只使用了execute,這個(gè)是沒(méi)有返回值的.而且如果任務(wù)拋出異常,則會(huì)直接在主線程打印出錯(cuò)誤堆棧的.其實(shí)ThreadPoolExecutor還有另外一個(gè)提交任務(wù)的方法,就是submit(Runnable task, T result)submit(Callable task),使用的就是我們這章節(jié)所講的內(nèi)容.大家可以自行寫(xiě)例子測(cè)試這兩個(gè)方法.

打賞

如果覺(jué)得我的文章寫(xiě)的還過(guò)得去的話,有錢就捧個(gè)錢場(chǎng),沒(méi)錢給我捧個(gè)人場(chǎng)(幫我點(diǎn)贊或推薦一下)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/69971.html

相關(guān)文章

  • Java線程進(jìn)階(四二)—— J.U.Cexecutors框架:Future模式

    摘要:本文首發(fā)于一世流云的專欄一模式簡(jiǎn)介模式是多線程設(shè)計(jì)模式中的一種常見(jiàn)模式,它的主要作用就是異步地執(zhí)行任務(wù),并在需要的時(shí)候獲取結(jié)果。二中的模式在多線程基礎(chǔ)之模式中,我們?cè)?jīng)給出過(guò)模式的通用類關(guān)系圖。 showImg(https://segmentfault.com/img/bVbiwcx?w=1000&h=667); 本文首發(fā)于一世流云的專欄:https://segmentfault.co...

    marek 評(píng)論0 收藏0
  • Java線程線程安全與異步執(zhí)行

    摘要:同步包裝器任何集合類使用同步包裝器都會(huì)變成線程安全的,會(huì)將集合的方法使用鎖加以保護(hù),保證線程的安全訪問(wèn)。線程池中的線程執(zhí)行完畢并不會(huì)馬上死亡,而是在池中準(zhǔn)備為下一個(gè)請(qǐng)求提供服務(wù)。 多線程并發(fā)修改一個(gè)數(shù)據(jù)結(jié)構(gòu),很容易破壞這個(gè)數(shù)據(jù)結(jié)構(gòu),如散列表。鎖能夠保護(hù)共享數(shù)據(jù)結(jié)構(gòu),但選擇線程安全的實(shí)現(xiàn)更好更容易,如阻塞隊(duì)列就是線程安全的集合。 線程安全的集合 Vector和HashTable類提供了線...

    taoszu 評(píng)論0 收藏0
  • 初讀《Java并發(fā)編程的藝術(shù)》-第十章:Executor框架 -10.1 Executor框架簡(jiǎn)介

    摘要:線程的啟動(dòng)與銷毀都與本地線程同步。操作系統(tǒng)會(huì)調(diào)度所有線程并將它們分配給可用的。框架的成員主要成員線程池接口接口接口以及工具類。創(chuàng)建單個(gè)線程的接口與其實(shí)現(xiàn)類用于表示異步計(jì)算的結(jié)果。參考書(shū)籍并發(fā)編程的藝術(shù)方騰飛魏鵬程曉明著 在java中,直接使用線程來(lái)異步的執(zhí)行任務(wù),線程的每次創(chuàng)建與銷毀需要一定的計(jì)算機(jī)資源開(kāi)銷。每個(gè)任務(wù)創(chuàng)建一個(gè)線程的話,當(dāng)任務(wù)數(shù)量多的時(shí)候,則對(duì)應(yīng)的創(chuàng)建銷毀開(kāi)銷會(huì)消耗大量...

    aisuhua 評(píng)論0 收藏0
  • Java 8 并發(fā)教程:線程和執(zhí)行器

    摘要:在這個(gè)示例中我們使用了一個(gè)單線程線程池的。在延遲消逝后,任務(wù)將會(huì)并發(fā)執(zhí)行。這是并發(fā)系列教程的第一部分。第一部分線程和執(zhí)行器第二部分同步和鎖第三部分原子操作和 Java 8 并發(fā)教程:線程和執(zhí)行器 原文:Java 8 Concurrency Tutorial: Threads and Executors 譯者:BlankKelly 來(lái)源:Java8并發(fā)教程:Threads和Execut...

    jsdt 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<