自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java并行編程:從并行任務(wù)集獲取反饋

開發(fā) 后端
要實現(xiàn)多線程的這種反饋,我們可以使用Callable接口。此接口的工作方式基本上與Runnable相同,但是執(zhí)行方法(call())會返回一個值,該值反映了執(zhí)行計算的結(jié)果。詳細(xì)請看下文

在并行任務(wù)啟動后,強制性地從并行任務(wù)得到反饋。

假想有一個程序,可以發(fā)送批郵件,還使用了多線程機制。你想知道有多少郵件成功發(fā)送嗎?你想知道在實際發(fā)送過程期間,這個批處理工作的實時進展嗎?

要實現(xiàn)多線程的這種反饋,我們可以使用Callable接口。此接口的工作方式基本上與Runnable相同,但是執(zhí)行方法(call())會返回一個值,該值反映了執(zhí)行計算的結(jié)果。

  1. package com.ricardozuasti;  
  2.  
  3. import java.util.concurrent.Callable;  
  4.  
  5. public class FictionalEmailSender implements Callable<Boolean>{  
  6.     private String to;  
  7.     private String subject;  
  8.     private String body;  
  9.     public FictionalEmailSender(String to, String subject, String body){  
  10.         this.to = to;  
  11.         this.subject = subject;  
  12.         this.body = body;  
  13.     }  
  14.  
  15.     @Override 
  16.     public Boolean call() throws InterruptedException {  
  17.         // 在0~0.5秒間模擬發(fā)送郵件  
  18.         Thread.sleep(Math.round(Math.random()*0.5*1000));  
  19.         // 假設(shè)我們有80%的幾率成功發(fā)送郵件  
  20.         if(Math.random()>0.2){  
  21.             return true;  
  22.         }else{  
  23.             return false;  
  24.         }  
  25.     }  
  26.       
  27. }  

注意:Callable接口可用于返回任意數(shù)據(jù)類型,因此我們的任務(wù)可以返回我們需要的任何信息。

現(xiàn)在,我們使用一個線程池ExecutorService來發(fā)送郵件,由于我們的任務(wù)是以Callable接口實現(xiàn)的,我們提交執(zhí)行的每個新任務(wù),都會得到一個Future引用。注意我們要使用直接的構(gòu)造器創(chuàng)建ExecutorService,而不是使用來自Executors的工具方法創(chuàng)建。這是因為使用指定類ThreadPoolExecutor提供了一些方法可以派上用場。

  1. package com.ricardozuasti;  
  2.  
  3. import java.util.concurrent.Future;  
  4. import java.util.concurrent.LinkedBlockingQueue;  
  5. import java.util.concurrent.ThreadPoolExecutor;  
  6. import java.util.concurrent.TimeUnit;  
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9.  
  10. public class Concurrency2 {  
  11.     public static void main(String[] args){  
  12.         try{  
  13.             ThreadPoolExecutor executor = new ThreadPoolExecutor(30301,  
  14.      TimeUnit.SECONDS, new LinkedBlockingQueue());  
  15.             List<Future<Boolean>> futures = new ArrayList<Future<Boolean>>(9000);  
  16.             // 發(fā)送垃圾郵件, 用戶名假設(shè)為4位數(shù)字  
  17.             for(int i=1000; i<10000; i++){  
  18.                 futures.add(executor.submit(new FictionalEmailSender(i+"@sina.com",  
  19.                         "Knock, knock, Neo""The Matrix has you...")));  
  20.             }  
  21.             // 提交所有的任務(wù)后,關(guān)閉executor  
  22.             System.out.println("Starting shutdown...");  
  23.             executor.shutdown();  
  24.               
  25.             // 每秒鐘打印執(zhí)行進度  
  26.             while(!executor.isTerminated()){  
  27.                 executor.awaitTermination(1, TimeUnit.SECONDS);  
  28.                 int progress = Math.round((executor.getCompletedTaskCount()  
  29. *100)/executor.getTaskCount());  
  30.                 System.out.println(progress + "% done (" +   
  31. executor.getCompletedTaskCount() + " emails have been sent).");  
  32.             }  
  33.             // 現(xiàn)在所有郵件已發(fā)送完, 檢查futures, 看成功發(fā)送的郵件有多少  
  34.             int errorCount = 0;  
  35.             int successCount = 0;  
  36.             for(Future<Boolean> future : futures){  
  37.                 if(future.get()){  
  38.                     successCount++;  
  39.                 }else{  
  40.                     errorCount++;  
  41.                 }  
  42.             }  
  43.             System.out.println(successCount + " emails were successfully sent, but " +  
  44.                     errorCount + " failed.");  
  45.         }catch(Exception ex){  
  46.             ex.printStackTrace();  
  47.         }  
  48.     }  
  49. }  

執(zhí)行這個類,輸出結(jié)果如下:

  1. Starting shutdown...  
  2. 1% done (118 emails have been sent).  
  3. 2% done (232 emails have been sent).  
  4. 3% done (358 emails have been sent).  
  5. 5% done (478 emails have been sent).  
  6. 6% done (587 emails have been sent).  
  7. 7% done (718 emails have been sent).  
  8. 9% done (850 emails have been sent).  
  9. 10% done (969 emails have been sent).  
  10. ……  

所有的任務(wù)都由ExecutorService提交,我們開始它的關(guān)閉(防止提交新任務(wù))并使用一個循環(huán)(實時場景,可能你會繼續(xù)做其它的事情)來等待,直至所有任務(wù)都被執(zhí)行完成、計算和打印當(dāng)前每次迭代的進度。

注意,你可以存儲executor引用,也可以在任意時間從其它線程查詢它的計算結(jié)果和報告進程進度。

最后,使用Future集合引用,我們得到ExecutorService提交的每個Callable接口,通知成功發(fā)送的郵件數(shù)量和發(fā)送失敗的郵件數(shù)量。

此結(jié)構(gòu)不但易于使用,還使得相關(guān)性得到清晰的隔離,在調(diào)度程序和實際任務(wù)之間提供了一個預(yù)定義的通信機制。

原文鏈接:http://blog.csdn.net/chszs/article/details/7418880

【編輯推薦】

  1. Java反射機制初探
  2. 不再糾結(jié)Java中的String類
  3. Java中常見IO的讀寫效率對比
  4. 棧的Java實現(xiàn)和棧的應(yīng)用舉例
  5. 實戰(zhàn)是硬道理:記Java技術(shù)面試
責(zé)任編輯:林師授 來源: chszs的博客
相關(guān)推薦

2010-06-02 08:53:51

.NET 4并行編程

2012-04-10 10:04:26

并行編程

2014-02-12 13:43:50

代碼并行任務(wù)

2009-05-13 15:38:45

微軟并行語言Axum

2017-04-13 19:20:18

Python代碼并行任務(wù)

2023-11-08 09:36:01

Java編程

2024-07-26 07:54:53

2010-03-26 19:03:19

F#異步并行模式

2015-10-13 09:18:00

.Net編程教程

2021-09-09 07:16:00

C#多線程開發(fā)

2011-09-22 09:41:16

JavaScript

2010-06-04 09:11:10

.NET并行編程

2018-06-14 09:38:53

Linux多核編程

2010-06-08 08:41:08

.NET 4并行編程

2023-11-01 20:10:53

分布式并行技術(shù)

2022-04-26 08:41:38

Swift并發(fā)系統(tǒng)iOS

2010-06-07 08:43:46

.NET 4并行編程

2012-10-10 09:14:50

PHPRPCPHP框架

2024-04-07 09:04:18

Parallel 類編程工具.NET

2022-10-20 23:15:10

PostgreSQL算法機制
點贊
收藏

51CTO技術(shù)棧公眾號