線程池提交同步或異步任務(wù)

提交Runnable任務(wù)

Runnable有一個run()函數(shù)尉姨,用于將耗時操作寫在其中,該函數(shù)沒有返回值。然后使用某個線程去執(zhí)行該runnable即可實現(xiàn)多線程,Thread類在調(diào)用start()函數(shù)后就是執(zhí)行的是Runnable的run()函數(shù)竟贯。

提交Callable任務(wù),F(xiàn)uture返回結(jié)果

Callable 在java 5中被引入逝钥, 作為Runnable 的一個對等(peer)屑那。 Callable除了有一個Call 方法而不是Run 方法外(和Runnable)本質(zhì)相同。 Call 方法有其它的能力去返回一個結(jié)果并且允許拋出檢查時異常。

Callable 任務(wù)提交所產(chǎn)生的結(jié)果可用后能夠被Future 獲取持际,F(xiàn)uture 可以被看作一個整理存儲Callable 計算結(jié)果的容器沃琅。callable的計算能持續(xù)在另一個線程中, 并且任何獲取一個Future 結(jié)果的嘗試都將被阻塞蜘欲,并且一旦(結(jié)果)變得可用益眉,便會返回結(jié)果。

public interface Future<V>Future 表示異步計算的結(jié)果姥份。它提供了檢查計算是否完成的方法呜叫,以等待計算的完成,并獲取計算的結(jié)果殿衰。計算完成后只能使用 get 方法來獲取結(jié)果,如有必要盛泡,計算完成前可以阻塞此方法闷祥。取消則由 cancel 方法來執(zhí)行。還提供了其他方法傲诵,以確定任務(wù)是正常完成還是被取消了凯砍。一旦計算完成,就不能再取消計算拴竹。如果為了可取消性而使用 Future 但又不提供可用的結(jié)果悟衩,則可以聲明 Future<?> 形式類型、并返回 null 作為底層任務(wù)的結(jié)果栓拜。

public interface Callable<V>返回結(jié)果并且可能拋出異常的任務(wù)座泳。實現(xiàn)者定義了一個不帶任何參數(shù)的叫做 call 的方法。

Callable 接口類似于 Runnable幕与,兩者都是為那些其實例可能被另一個線程執(zhí)行的類設(shè)計的挑势。但是 Runnable 不會返回結(jié)果,并且無法拋出經(jīng)過檢查的異常啦鸣。

Runnable 提供了一種包裹要被在一個不同的線程中執(zhí)行的代碼的方式潮饱。它有一個缺陷, 不能從執(zhí)行中返回結(jié)果诫给。僅有的一種從一個Runnable 的執(zhí)行中返回值的方式是把結(jié)果賦值給一個在Runnable 外部作用域中可訪問的變量香拉。

二者區(qū)別

Callable 和 Future接口的區(qū)別

  • Callable規(guī)定的方法是call(),而Runnable規(guī)定的方法是run().
  • Callable的任務(wù)執(zhí)行后可返回值中狂,而Runnable的任務(wù)是不能返回值的凫碌。
  • call()方法可拋出異常,而run()方法是不能拋出異常的吃型。
  • 運行Callable任務(wù)可拿到一個Future對象证鸥, Future表示異步計算的結(jié)果。
  • 它提供了檢查計算是否完成的方法,以等待計算的完成枉层,并檢索計算的結(jié)果泉褐。
  • 通過Future對象可了解任務(wù)執(zhí)行情況,可取消任務(wù)的執(zhí)行鸟蜡,還可獲取任務(wù)執(zhí)行的結(jié)果膜赃。
  • Callable是類似于Runnable的接口,實現(xiàn)Callable接口的類和實現(xiàn)Runnable的類都是可被其它線程執(zhí)行的任務(wù)揉忘。

使用案例

模擬任務(wù)

public class PollingResult {

    public Random random = new Random();

    public void executeTask(int sleepTime) {
        try {
            int value = random.nextInt(10);
            while(true){
                // 模擬輪詢過程跳座,隨機耗時1-5s
                Thread.sleep(sleepTime);
                if ( value % 2 == 0) {
                    // 當(dāng)前隨機數(shù)是偶數(shù)直接結(jié)束循環(huán)
                    break;
                }
                value = random.nextInt(10);
            }
            System.out.println("SubmitRunnableTask:"+ value + "是偶數(shù)!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public Integer executeTask(int sleepTime, boolean callback) {
        try {
            int value = random.nextInt(10);
            while(true){
                // 模擬輪詢過程泣矛,隨機耗時1-5s
                Thread.sleep(sleepTime);
                if ( value % 2 == 0) {
                    // 當(dāng)前隨機數(shù)是偶數(shù)直接結(jié)束循環(huán)
                    break;
                }
                value = random.nextInt(10);
            }
            return value;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return 0;
    }
}

提交Callback任務(wù)

public class SubmitCallableTask {
    /**
     * 構(gòu)造一個并發(fā)數(shù)是5疲眷,阻塞隊列是0,一滿就拋異常的線程池
     */
    public static ExecutorService THREAD_POOL = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS, new SynchronousQueue<>());

    public Random random = new Random(10);

    private PollingResult pollingResult = new PollingResult();

    public void execute() {
        Future<Integer> future = THREAD_POOL.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return pollingResult.executeTask(random.nextInt(1000), true);
            }
        });
        try {
            // get() 方法用來獲取執(zhí)行結(jié)果您朽,這個方法會產(chǎn)生阻塞狂丝,會一直等到任務(wù)執(zhí)行完畢才返回
            System.out.println("SubmitCallableTask:"+future.get() + "是偶數(shù)!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

提交Runnable任務(wù)

public class SubmitRunnableTask {
    /**
     * 構(gòu)造一個并發(fā)數(shù)是5哗总,阻塞隊列是0几颜,一滿就拋異常的線程池
     */
    public static ExecutorService THREAD_POOL = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS, new SynchronousQueue<>());

    public Random random = new Random(10);

    private PollingResult pollingResult = new PollingResult();

    public void execute() {
        THREAD_POOL.submit(() -> {
            // 提交帶執(zhí)行的任務(wù)
            pollingResult.executeTask(random.nextInt(1000));
        });
    }
}

測試并發(fā)數(shù)

public class MainTask {

    private static SubmitRunnableTask submitRunnableTask = new SubmitRunnableTask();

    private static SubmitCallableTask submitCallableTask = new SubmitCallableTask();

    public static void main(String[] args) {
        // 提交異步任務(wù),這個不會拋異常
        for(int i=0;i<10;i++){
            submitCallableTask.execute();
        }
        // 同時提交10個任務(wù)讯屈,肯定會拋異常
        for(int i=0;i<10;i++){
            submitRunnableTask.execute();
        }
    }
}

源碼參考

線程池提交異步/同步任務(wù)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蛋哭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子涮母,更是在濱河造成了極大的恐慌谆趾,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叛本,死亡現(xiàn)場離奇詭異棺妓,居然都是意外死亡,警方通過查閱死者的電腦和手機炮赦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門怜跑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吠勘,你說我怎么就攤上這事性芬。” “怎么了剧防?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵植锉,是天一觀的道長。 經(jīng)常有香客問我峭拘,道長俊庇,這世上最難降的妖魔是什么狮暑? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮辉饱,結(jié)果婚禮上搬男,老公的妹妹穿的比我還像新娘。我一直安慰自己彭沼,他們只是感情好缔逛,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著姓惑,像睡著了一般褐奴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上于毙,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天敦冬,我揣著相機與錄音,去河邊找鬼唯沮。 笑死匪补,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的烂翰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蚤氏,長吁一口氣:“原來是場噩夢啊……” “哼甘耿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起竿滨,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤佳恬,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后于游,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體毁葱,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年贰剥,在試婚紗的時候發(fā)現(xiàn)自己被綠了倾剿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蚌成,死狀恐怖前痘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情担忧,我是刑警寧澤芹缔,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站瓶盛,受9級特大地震影響最欠,放射性物質(zhì)發(fā)生泄漏示罗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一芝硬、第九天 我趴在偏房一處隱蔽的房頂上張望蚜点。 院中可真熱鬧,春花似錦吵取、人聲如沸禽额。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脯倒。三九已至,卻和暖如春捺氢,著一層夾襖步出監(jiān)牢的瞬間藻丢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工摄乒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留悠反,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓馍佑,卻偏偏與公主長得像斋否,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拭荤,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容