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 失败。

但是使用上面的代码,我只得到没有任务。即5个任务

谁能告诉我如何从所有并发任务中获得反馈(不是完成的任务数量)。

4

2 回答 2

1

MyTask返回 a String(implements 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)。它更容易,不应该更慢。

于 2012-10-29T15:50:53.787 回答
0

我可以看到您的调用方法被声明为返回一个字符串,但您的代码没有返回任何内容(可能是不完整的代码段)。而且从您的陈述中,我了解到您正在返回任务是否完成,而不是邮件是否已发送。您可以sendEmailToUser根据邮件是否已成功发送成功返回失败并使用获取结果Future.get

于 2012-10-29T15:48:44.583 回答