3

複数 (500、1000、2000) のユーザーにメールを送信したい。

を使用してそれを行い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つのタスクが返されます。

しかし、失敗したメールの数と送信された成功したメールの数として出力が必要でした。

たとえば、500 人の電子メール ユーザーがいて、20 人が失敗した場合、出力は 480 件の成功と 20 件の失敗になります。

しかし、上記のコードでは、 no of task しか得られません。すなわち5タスク

すべての同時タスクからフィードバックを得る方法を誰か教えてもらえますか (完了したタスクの数ではありません)。

4

2 に答える 2

1

あなたは(implements ) をMyTask返しますが、これはあなたの場合にはあまり意味がありません。必要な他のタイプを自由に返すことができます。残念ながら、結果を含めるにはいくつかの単純な POJO が必要です。StringCallable<String>

public class Result {

    private final int successCount;
    private final int failureCount;

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

}

そして、与えられたバッチが完了した後にそれを返します (implement Callable<Result>)。もちろん、MyTask失敗した電子メールの数を追跡し、ラップされた正しい値を返す必要がありますResult

ただし、コードを改善できる方法がいくつかあります。まず第一に、使用する範囲を渡す代わりに-startValue, endValueこれにより、コードが大幅に簡素化されます:MyTaskuserEmailList.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メールを 1 通だけ送信するように作成することには何の問題もありません。特定のバッチでカウントを集計する代わりに、1 つのタスク (1 つの電子メール) の結果をチェックするだけです - 何もないか、例外 (または単一Boolean)。はるかに簡単で、遅くなることはありません。

于 2012-10-29T15:50:53.787 に答える
0

call メソッドが文字列を返すように宣言されていることがわかりましたが、コードは何も返していません (おそらく不完全なスニペット)。そして、あなたの発言から、メールが送信されたかどうかではなく、タスクが完了したかどうかに関係なく戻ってくることがわかりました。sendEmailToUserメールが正常に送信されたかどうかに応じて失敗の成功を返し、次を使用して結果を取得できます。Future.get

于 2012-10-29T15:48:44.583 に答える