Filter email with JavaMail
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...