简体   繁体   English

Java ExecutorService获取所有任务的反馈

[英]Java ExecutorService get feedback for all tasks

I want to send email to multiple(500,1000,2000) users. 我想向多个(500,1000,2000)用户发送电子邮件。

I have done that using ExecutorService . 我已经使用ExecutorService完成了这项工作。

But now I want to collect the number of successful emails sent and the number of failed emails out of total records. 但现在我想收集已发送的成功电子邮件的数量以及总记录中失败的电子邮件数量。

I have implemented this like: 我实现了这个:

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)){
}
 }

} }

But future.get() returning me number of task completed. 但是future.get()返回完成的任务数量。 so from above code it will return me 5 task. 所以从上面的代码它将返回我5个任务。

But I wanted output as no of failed emails and number of successful email sent. 但是我希望输出没有失败的电子邮件和成功发送的电子邮件数量。

for eg if there are 500 email users and if 20 falied , then output should be 480 success and 20 failed. 例如,如果有500个电子邮件用户,如果有20个电子邮件用户,那么输出应该是480次成功而20次失败。

But with above code I am getting only no of task . 但是使用上面的代码我只能得到任务。 ie 5 task 即5个任务

Can anybody tell me how I can get feedback from all concurrent tasks ( Not the number of tasks completed). 任何人都可以告诉我如何从所有并发任务中获得反馈( 完成任务的数量)。

Your MyTask returns a String (implements Callable<String> ), which doesn't make much sense in your case. 你的MyTask返回一个String (实现Callable<String> ),这在你的情况下没有多大意义。 You are free to return any other type you want. 您可以自由返回您想要的任何其他类型。 Unfortunately you'll need some simple POJO to contain the results, eg: 不幸的是,你需要一些简单的POJO来包含结果,例如:

public class Result {

    private final int successCount;
    private final int failureCount;

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

}

And return it after given batch is done (implement Callable<Result> ). 并在完成给定批处理后返回它(实现Callable<Result> )。 Of course your MyTask will then have to keep track of how many e-mails failed and return correct values wrapped around Result . 当然,你的MyTask必须跟踪有多少电子邮件失败并返回包裹在Result周围的正确值。

However I see several ways your code can be improved. 但是我看到了几种改进代码的方法。 First of all instead of passing startValue, endValue range to MyTask just use userEmailList.subList(startValue, endValue) - which will simplify your code a lot : 首先强似的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(...);
    }
 }

On the other hand there is nothing wrong in creating MyTask to send just one e-mail. 另一方面,创建MyTask只发送一封电子邮件并没有错。 That instead of aggregating counts in given batch you simply check the result of one task (one e-mail) - either nothing or exception (or single Boolean ). 您只需检查一个任务(一个电子邮件)的结果 - 无论是否为异常(或单个Boolean ),而不是聚合给定批次中的计数。 It's much easier and shouldn't be slower. 它更容易,也不应该慢。

I could see that your call method is declared to return a String but your code doesn't return anything (probably incomplete snippet). 我可以看到你的调用方法被声明为返回一个String但你的代码没有返回任何东西(可能是不完整的片段)。 And from your statement, I understand that you are returning whether the task is completed or not and not whether the mail has been sent. 从您的陈述中,我了解到您将返回任务是否完成,而不是邮件是否已发送。 You could make the sendEmailToUser return the success of failure depending on whether the mail has been sent successfully and get the result using Future.get 您可以使sendEmailToUser返回失败成功,具体取决于邮件是否已成功发送并使用Future.get获取结果

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM