Java - 并行发送多个邮件

时间:2018-04-05 12:15:27

标签: java parallel-processing java-8 java-stream

我要求并行发送多封邮件。假设我有10个人的电子邮件(我的实际要求有大约100个收件人)。为了向所有这10个人发送邮件,我需要点击多个服务来收集基于emailId的信息,这将花费很多时间。说我的电子邮件触发服务是完全隔离的功能,我没有任何邮件触发顺序的约束。

首先,我使用如下所示的常规方式,但它按顺序触发并占用更多时间。

public static void main(String[] args) {

    List<String> emails = Lists.newArrayList();
    emails.add("first-person@gmail.com");
    emails.add("second-person@gmail.com");
    emails.add("third-person@gmail.com");
    emails.add("fourth-person@gmail.com");
    emails.add("fifth-person@gmail.com");
    emails.add("sixth-person@gmail.com");
    emails.add("seventh-person@gmail.com");
    emails.add("eighth-person@gmail.com");
    :
    :

    for(String email: emails) {
        sendMail(email);
    }
}
private static void sendMail(final String email) {
    // function will call many other services for getting the information required for sending the email
    try {
        Thread.sleep(10000);
        System.out.println("Sending Mail for:"+email);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

其次我听说过Java8并行流(我对此非常陌生),所以想到如下所示使用它。似乎可以比顺序命令更快地触发邮件

public static void main(String[] args) {

    List<String> emails = Lists.newArrayList();
    emails.add("first-person@gmail.com");
    emails.add("second-person@gmail.com");
    emails.add("third-person@gmail.com");
    emails.add("fourth-person@gmail.com");
    emails.add("fifth-person@gmail.com");
    emails.add("sixth-person@gmail.com");
    emails.add("seventh-person@gmail.com");
    emails.add("eighth-person@gmail.com");
    :
    :

    emails.stream().parallel().forEach(email -> {
        sendMail(email);
    });
}
private static void sendMail(final String email) {
    // function will call many other services for getting the information required for sending the email
    try {
        Thread.sleep(10000);
        System.out.println("Sending Mail for:"+email);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

任何人都可以告诉我,使用Java8并行流的方法对于这种方法是否正确

1 个答案:

答案 0 :(得分:3)

不,不是。无论如何,您使用它的方式将解析为非并发。

您想要的是ExecutorService,您可以将邮件发送逻辑传递给。{/ p>

ExecutorService mailService = Executors.newFixedThreadPool(threadCount);
for (String email : emails) {
    mailService.submit(() -> sendMail(email));
}

编辑:

自评论中提出: 您也可以使用几乎相同的构造逐个发送它们,但是:

ExecutorService mailService = Executors.newSingleThreadExecutor();

这将逐个调用sendMail。 在像emails.forEach(m -> sendMail(m))这样的直接循环中执行此操作的区别在于发送本身发生在另一个线程中,这意味着主线程不会阻止对sendMail的调用,并且可以自由地执行其他操作。