2012-10-29 60 views
3

我想向多個(500,1000,2000)用戶發送電子郵件。Java ExecutorService獲取所有任務的反饋

我已經做到了用ExecutorService

但現在我想收集發送成功的電子郵件的數量和失敗的郵件的出總記錄數。

我已經實現了這個名字:

int startValue=0; 
int endValue=0; 
List userEmailList = getListFromDB(); 
ExecutorService e = Executors.newFixedThreadPool(10); 
Collection c = new ArrayList(); 

while (someflag) 
{ 
// in MyTask class I am sending email to users. 
c.add(new MyTask(startValue, endValue,userEmailList)); 
}  
e.invokeAll(c); //Here I am calling invokeall . 
pool.shutdown(); 


public class MyTask implements Callable<String> { 
    MyTask(startValue, endValue,userEmailList){ 
    } 

    public String call(){ 
//e.g. batch 1 will have - startValue => endValue = 0 -100 
//e.g. batch 2 will have - startValue => endValue = 101 -199 
//e.g. batch 3 will have - startValue => endValue = 200 -299 
//e.g. batch 4 will have - startValue => endValue = 300 -399 
//e.g. batch 5 will have - startValue => endValue = 400 - 499 

for(int i=startValue;i<endValue;i++){ 
     sendEmailToUser(userEmailList.get(i)){ 
} 
} 

}

但那麼Future.get()返回我的任務完成的數量。所以從上面的代碼它會返回我5任務。

但我想輸出沒有失敗的電子郵件和成功的電子郵件的號碼發送的。

爲e.g如果有500個電子郵件用戶,如果20 falied,那麼輸出應該是480的成功與失敗20。

但隨着上面的代碼,我只得到沒有任務的。即5任務

任何人都可以告訴我如何從所有併發任務中獲得反饋(不是已完成任務的數量)。

+0

您可以發佈完整的代碼片段。我認爲你需要返回類型爲'List '而不是'String' –

回答

0

我看得出來,您的通話方法聲明爲返回一個字符串,但您的代碼不返回任何東西(可能是不完整的片段)。從你的陳述中,我明白你是否正在返回任務是否完成,而不是郵件是否已經發送。你可以做的sendEmailToUser返回取決於是否郵件已經發送成功失敗的成功,並得到使用Future.get

+0

感謝所有幫助。問題已得到解決。 – user1783350

1

MyTask回報String(實現Callable<String>),這並沒有太大的意義,你的情況的結果。你可以自由地返回你想要的任何其他類型。不幸的是,你需要一些簡單的POJO遏制的結果,例如:

public class Result { 

    private final int successCount; 
    private final int failureCount; 

    public Result(int successCount, int failureCount) { 
     this.successCount = successCount; 
     this.failureCount = failureCount; 
    } 

} 

並返回給定批次完成後(實施Callable<Result>)。當然,你的MyTask將不得不跟蹤有多少電子郵件失敗,並返回正確的價值包裹Result

但是我看到幾種方法可以改善您的代碼。首先強似startValue, endValue範圍MyTask只使用userEmailList.subList(startValue, endValue) - 這將簡化代碼很多

new MyTask(userEmailList.subList(startValue, endValue)); 
//... 

public class MyTask implements Callable<Result> { 
    MyTask(userEmailList){ 
    } 

    public Result call(){ 
     for(email: userEmailList) { 
      sendEmailToUser(email); 
      //collect results here 
     } 
     return new Result(...); 
    } 
} 

在另一方面並無不妥創建MyTask派只是一個電子郵件。不是在給定的批次中彙總計數,而是簡單地檢查一項任務(一封電子郵件)的結果 - 無論是無例外還是異常(或單個Boolean)。這更容易,不應該更慢。