Filter email with JavaMail I'm trying to develop code to filter my e-mail with JavaMail, but I doubt it's the best way of doing this. And I want to collect all messages without attachment.

package service.forkinjoin;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.RecursiveAction;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.internet.MimeBodyPart;

import service.FileUtil;

public class ForkSortMessages extends RecursiveAction {

    private static final long serialVersionUID = -1092415796824205832L;
    private List&lt;Message&gt; listMessages;
    private List&lt;Message&gt; listMessagesToDelete;

    public ForkSortMessages(List&lt;Message&gt; listMessages, List&lt;Message&gt; listMessagesToDelete) {
        this.listMessages = listMessages;
        this.listMessagesToDelete = listMessagesToDelete;
    }

    @Override
    protected void compute() {

        List&lt;RecursiveAction&gt; actions = new ArrayList&lt;&gt;();

        if (this.listMessages.size() &lt;= Runtime.getRuntime().availableProcessors()) {
            try {
                this.separateMessages();
            } catch (MessagingException | IOException e) {
                e.printStackTrace();
            }
        } else {

            int end = this.listMessages.size() / 2;
            actions.add(new ForkSortMessages(this.listMessages.subList(0, end), this.listMessagesToDelete));
            end += this.listMessages.size() % 2 == 0 ? 0 : 1;
            actions.add(new ForkSortMessages(this.listMessages.subList(end, this.listMessages.size()), this.listMessagesToDelete));
            invokeAll(actions);
        }
    }

    private void separateMessages() throws MessagingException, IOException {

        for (Message message : this.listMessages) {

            if ((this.hasNoAttachment(message.getContentType()) || (this.hasNoXmlAttachment(message)))) {
                listMessagesToDelete.add(message);
            }
        }
    }

    private boolean hasNoAttachment(String content) {
        return !content.contains("multipart/MIXED");
    }

    private boolean hasNoXmlAttachment(Message message) throws IOException, MessagingException {

        Multipart multipart = (Multipart) message.getContent();

        for (int i = 0; i &lt; multipart.getCount(); i++) {

            MimeBodyPart mimeBodyPart = (MimeBodyPart) multipart.getBodyPart(i);

            if (Part.ATTACHMENT.equalsIgnoreCase(mimeBodyPart.getDisposition())) {

                if (FileUtil.isXmlFile(mimeBodyPart.getFileName())) {
                    return false;
                }
            }
        }

        return true;
    }
}


So what can I do to improve my code? I've tried to do like Oracle tutorial but I can't.
In order to correctly work in parallel, you must follow the Actor Model, which basically says that each iteration should not share memory when doing their work. In your code, you pass a List&lt;Message&gt; to the child processes, which they are expected to fill. Each child process changes his own copy of the list, which makes the final result unexpected.

To build your actors correctly, each should create its own solution vector, and later its parent process should merge the result of the children, and pass them on (you can see samples here).

If the order of the messages is important to you, even this is not enough, since you don't know which child process will finish first, so the messages in the resulting list will not be in the same order as in the input list.

After all being said and done - you might find out that you do not get better performance, and sometimes even worse performance.

My suggestion is to keep it simple - the actual work you are doing on the array is simple enough - do a straight forward iteration. By they way you describe your use-case - at most you will have to wait a couple of minutes (tens of minutes?) for the initial bulk to be computed, but at least you'll be confident that you have the correct result. I assure you it would take less time to run it synchronously than to develop and debug a fork/join solution...