javamultithreadingexecutor

Proper way of running many long lived tasks in Java


I have a Java application that listens to 15 incoming message queues services (Such as rabbitMQ, kafka, etc). Each queue is being listened on a separate Thread. This is, on startup, I have 15 lines of Executors.newSingleThreadExecutor(new QueueListener("SomeQueueToListenTo"));

This QueueListener threads are while true loops, so they will live until the JVM exits.

My question is: Is there a better way (better being: clean code/performance wise) to initialize these long lived threads?

For example: Is there a difference between doing Executors.newSingleThreadExecutor 15 times and creating a single threadpool with 15 threads, and then submit each listener to this threadpool?

Thanks in advance.


Solution

  • For example: Is there a difference between doing Executors.newSingleThreadExecutor 15 times and creating a single threadpool with 15 threads, and then submit each listener to this threadpool?

    In terms of runtime I don't think there is a difference but in terms of code cleanliness and maintainability, I would say that the single executor is cleaner. Otherwise you are going to have 15 variables and 15 shutdown calls. What happens if you miss one?

    ExecutorService someQueuePool =
        Executors.newSingleThreadExecutor(new QueueListener("SomeQueueToListenTo"));
    ExecutorService otherQueuePool =
        Executors.newSingleThreadExecutor(new QueueListener("..."));
    ...
    someQueuePool.shutdown();
    otherQueuePool.shutdown();
    

    as opposed to:

    ExecutorService listenerThreadPool = Executors.newCachedThreadPool();
    listenerThreadPool.submit(new QueueListener("SomeQueueToListenTo"));
    listenerThreadPool.submit(new QueueListener("..."));
    ...
    listenerThreadPool.shutdown();
    

    This QueueListener threads are while true loops, so they will live until the JVM exits.

    You should consider handling the thread interrupt and doing a graceful shutdown of the various queue clients. They could be in the following loop:

    while (!Thread.currentThread().isInterrupted()) {
    

    and then you would shutdown the pool with:

    listenerThreadPool.shutdownNow();
    

    I tend to poll for a couple of seconds or so and check for interrupt and then poll again if the clients aren't interruptible.