Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't i instantiate ThreadPoolExecutor with BlockingQueue<Callable>; why only BlockingQueue<Runnable>?

My understanding is that callable was added in 1.5 and the runnable interface was kept as-is to prevent the world from ending. Why can't I instantiate a ThreadPoolExecutor(core, max, tu, unit, new BlockingQueue<Callable>()) - why does the queue necessarily take runnable only? Internally, if i were to submit, invokeAll, invokeAny callables, this should be fine right? Also, would shutDownNow() return a list of callables?

like image 909
foamroll Avatar asked Dec 16 '22 07:12

foamroll


2 Answers

You can submit Callables, but they get wrapped internally as Runnables (actually FutureTasks, which implement Runnable). shutDownNow() is only going to return Runnables, just like it says on the tin.

If you want to get the list of Callables that haven't been run, you'll need to keep track of them yourself somehow (e.g., keep a list of them and make them responsible for removing themselves from the list when they're called.)

like image 55
David Moles Avatar answered Jan 13 '23 09:01

David Moles


As a more general answer, you can't influence the runtime behavior of a Java program by changing a type parameter. No if branch can be re-routed based on type parameters. If you ever find yourself in a situation where you wish to get a different behavior from an API, never look for the solution in the choice of type parameters.

In this particular case, a Runnable is a more generic type of object: it is a unit of work that the internals of the Executor can submit to a thread. For example, the Runnable can contain code which calls a Callable and saves its result somewhere.

like image 35
Marko Topolnik Avatar answered Jan 13 '23 09:01

Marko Topolnik