FixedThreadPool uses LinkedBlockingQueue of Integer.MAX_VALUE :
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
Thus, its affectively non-blocking, since you could use offer / put million Runnable instances for it, certainly this is an unreasonable use of memory to store millions of objects, although your fixedPoolSize would be comparatively much smaller, say, 5/10.
One approach that would directly improve this scenario is to use FixedThreadPool with a finite queue size:
int nThreads = 10; int maxQSize = 1000; ExecutorService service = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(maxQSize))
With the above call, your put will block 1000 runnables in Q , but as soon as some of them end, put will continue. Performing invokeAll , there will be 10 running threads and no more than 1000 executable instances.
harsh source share