Alex Man
Alex Man

Reputation: 4886

Java - Sending Multiple Mails in Parallel

I have a requirement to send multiple mails in parallel. Lets say I have 10 person emails (my actual requirement have around 100's of recipients). For sending mails to all those 10 people, I need to hit multiple services for collecting information based on the emailId and it will take a lot of time. Having said my email trigger service is totally isolated function, and I don't have any constraint in the order of mail triggering.

Firstly I used the normal way like as shown below, but it is triggering in sequential order and taking more time.

public static void main(String[] args) {

    List<String> emails = Lists.newArrayList();
    emails.add("[email protected]");
    emails.add("[email protected]");
    emails.add("[email protected]");
    emails.add("[email protected]");
    emails.add("[email protected]");
    emails.add("[email protected]");
    emails.add("[email protected]");
    emails.add("[email protected]");
    :
    :

    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();
    }
}

Secondly I heard abt Java8 parallel streams (I am very much new to this), So thought of using it like as shown below. It seems a to trigger the mails a little more faster than the sequential order

public static void main(String[] args) {

    List<String> emails = Lists.newArrayList();
    emails.add("[email protected]");
    emails.add("[email protected]");
    emails.add("[email protected]");
    emails.add("[email protected]");
    emails.add("[email protected]");
    emails.add("[email protected]");
    emails.add("[email protected]");
    emails.add("[email protected]");
    :
    :

    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();
    }
}

Can anyone tell me whether my approach of using Java8 parallel stream is correct for this approach

Upvotes: 2

Views: 1198

Answers (1)

daniu
daniu

Reputation: 15008

No, it's not. The way you use it will resolve to non-concurrent anyway.

What you want is to have an ExecutorService which you can pass your mail sending logic to.

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

EDIT:

Since it came up in the comments: You can just as well send them one by one with pretty much the same construct, but:

ExecutorService mailService = Executors.newSingleThreadExecutor();

This will call sendMail one by one. The difference to doing it in a straight loop like emails.forEach(m -> sendMail(m)) is that the sending itself is happening in another thread, meaning the main thread doesn't block on calls to sendMail and is free to do other things.

Upvotes: 3

Related Questions