18

I want to use the same thread pool throughout my application. To this end, I can make ExecutorService static and global so that I can invoke ThreadUtil.executorService to get ExecutorService when I need it.

public class ThreadUtil {
    public static final ExecutorService executorService = Executors.newCachedThreadPool();
}

Is it OK to instance multiple thread pools like this?

In addition, my application is a TCP server. If I don't know how big the pool should be, is it ok to simply use newCachedThreadPool?

MarsAtomic
  • 10,436
  • 5
  • 35
  • 56
bylijinnan
  • 756
  • 3
  • 11
  • 27

3 Answers3

6

When an instance with the same properties is to be used anywhere in your program, it is logical to declare it static and final instead of re-creating the instance each time but I would personally opt for a Singleton pattern instead of directly giving public access to the instance.

As for your second query, I don't see any problem with it. The first sentence of the documentation for newCachedThreadPool says

Creates a thread pool that creates new threads as needed

since you don't know how many threads will be created, this is the most logical choice.

Note that newCachedThreadPool will re-use old threads when they are available to increase performance.

Jean-François Savard
  • 20,626
  • 7
  • 49
  • 76
0

I would not make it directly global. At least wrap it in a class so you can easily use more than one pool. Having a pool of thread pool is very useful when you need more than one kind of job/ jobs with different priority. Just put fewer threads in the other pool and/or lower priority threads (by over riding the thread factory). For a sample can see https://github.com/tgkprog/ddt/tree/master/DdtUtils/src/main/java/org/s2n/ddt/util/threads

Usage :

//setup
PoolOptions options = new PoolOptions();
options.setCoreThreads(2);
options.setMaxThreads(33);
DdtPools.initPool("poolA", options);
Do1 p = null;


  // Offer a job:
  job = new YourJob();
  DdtPools.offer("poolA", job);

Also do not use a cached pool as it can grow as needed, not a good idea with TCP which can block indefinately. You want to use a controlled pool. The above library can be reinitialized if needed (increase number of threads while allowing current jobs to process before the old pool is discarded to GC).

Can make a utility jsp/ servlet for those ops like https://github.com/tgkprog/ddt/blob/master/Core/src/main/web/common/poolEnd.jsp and https://github.com/tgkprog/ddt/blob/master/Core/src/main/web/common/threads.jsp

tgkprog
  • 4,493
  • 4
  • 41
  • 70
0

If you have only ExecutorServivce for your application, you can proceed with static global.

newCachedThreadPool() and newFixedThreadPool() both does not provide control on queue of Callable/Runnable tasks. They use unbounded queue, which may result into degraded performance of the system with respect to performance.

I prefer to use ThreadPoolExecutor which provides better control on various parameters like Queue Size, Rejection Handler, Thread factory etc.

public ThreadPoolExecutor(int corePoolSize,
                  int maximumPoolSize,
                  long keepAliveTime,
                  TimeUnit unit,
                  BlockingQueue<Runnable> workQueue,
                  RejectedExecutionHandler handler)

Or

public ThreadPoolExecutor(int corePoolSize,
                  int maximumPoolSize,
                  long keepAliveTime,
                  TimeUnit unit,
                  BlockingQueue<Runnable> workQueue,
                  ThreadFactory threadFactory,
                  RejectedExecutionHandler handler)

Refer to below post for more details:

FixedThreadPool vs CachedThreadPool: the lesser of two evils

Anatoly Shamov
  • 2,608
  • 1
  • 17
  • 27
Ravindra babu
  • 37,698
  • 11
  • 250
  • 211