I would make a subclass of ThreadPoolExecutor.
When you setup your ThreadPoolExecutor you want to set the corePoolSize
and the maximumPoolSize
to Runtime.getRuntime().availableProcessors()
(Look at Executors.newFixedThreadPool()
to see why this works).
Next you want to make sure that your Queue
also implements Deque
. LinkedBlockingDeque
is an example but you should shop around to see which one will work best for you. A Deque
allows you to get stack like LIFO behavior which is exactly what you want.
Since everything (submit()
, invokeAll()
) funnels through execute()
you will want to override this method. Basically do what you described above:
Check if all threads are running. If not simply start the new runnable on an available thread. If all the threads are already running then you need to find the one running the oldest runnable, stop the runnable, re-queue the runnable somewhere (maybe at the beginning?), and then start your new runnable.