4

I would like to use a thread pool to process a list of items and then wait for them to complete. I also need to be able to time it out after 4 minutes of processing if they are not all completed.

This is what I have at the moment

ForkJoinPool threadPool = new ForkJoinPool(Runtime.getRuntime().availableProcessors() * 2);

list.forEach(entry -> threadPool.execute(() -> {
    // processing
}));

if (!threadPool.awaitQuiescence(4, TimeUnit.MINUTES)) {
    // send alert about delay
}

The problem is that sometimes this approach will use the main thread to process one of the list items meaning that the awaitQuiescence will not start until after that one completes. Is there any other Thread Pool which allows something similar but guarantees not to use the main thread or is there a way to configure ForkJoinPool to not?

sparkdoo
  • 522
  • 1
  • 5
  • 13
  • Why not just execute it on a new thread? And "sometimes it'll execute on the main thread" doesn't really make sense. You're saying the results are inconsistent, as in the `ForkJoinPool` chooses whether to use the main thread or not? – Vince Jul 22 '16 at 02:45
  • ForkJoinPool does seem to be inconsistent. I have logging within the processing that records the thread being used and sometimes it only uses ones called ForkJoinPool-1-worker-[n] and other times one of the threads is the one that triggered it. – sparkdoo Jul 22 '16 at 03:46
  • 2
    There is no way to avoid the submitting thread from being used. The submitting thread is necessary to achieve an acceptable level of performance, with a caveat as I point out here: http://coopsoft.com/ar/Calamity2Article.html#submit – edharned Jul 22 '16 at 13:51
  • Is there an alternative construct that I could use instead? – sparkdoo Jul 24 '16 at 22:32
  • No alternative construct. You could use a micro-service if you want full feature: https://sourceforge.net/projects/tymeacdse/?source=navbar – edharned Jul 26 '16 at 21:47

1 Answers1

0

I think the problem is that you still iterate (list.forEach) within the main thread. Use a parallel stream and delegate the whole computation to your pool:

ForkJoinPool pool = new ForkJoinPool(Runtime.getRuntime().availableProcessors() * 2);

pool.execute(() -> {
    list.parallelStream().forEach(item -> {
        // processing
    });
});

if (!pool.awaitQuiescence(4L, TimeUnit.MINUTES)) {
    // send alert about delay
}

I recommend reading this question (and the given answers) to see how to use ForkJoinPool and parallel streams.

Community
  • 1
  • 1
beatngu13
  • 7,201
  • 6
  • 37
  • 66