Change queue size of a ThreadPoolExecutor - java

I need to be able to change the size of the task queue of a ThreadPoolExecutor. Of course, the BlockingQueue doesn't support changing the size, and the ThreadPoolExecutor doesn't support changing the queue.
So, the method I've come up with is to use ThreadPoolExecutor.shutdownNow(), which gives me back a list of the Runnables that haven't yet been executed. Then I can create a new executor with the desired queue size and re-submit all of the tasks.
The issue is with the tasks in progress at the time of the shutdownNow() call. As far as I can tell from the javadoc, the executor will call Thread.interrupt() on all threads currently executing a taks. I don't want my tasks to be killed. This question may have been a long-winded way of asking how to write my tasks such that Thread.interrupt() won't have any effect?

Using a mix of "shutdown()" (not shutdownNow()), then polling with getPoolSize()/isTerminated(), you could (a) stop the existing the pool . Then (b) simultaneously (in a separate thread) a new queue with the desired size could be created. You would have a tradeoff here in terms of: can you allow there to temporarily exist more threads than the desired number (while the first pool is shutting down).

You should use isTerminated() method to check Executor state but make sure before calling isTerminated method you should call shutdown() otherwise isTermainated method aleays return false.

Related

Behavior of ThreadPoolExecutor with keepAliveTime = 0 and corePoolSize = 0

Does setting ThreadPoolExecutor's keepAliveTime and corePoolSize to 0 make it create a new Thread for every task? Is it guaranteed no Thread will ever be reused for any task?
BTW I want to set the maximumPoolSize to 100 or so. I cannot afford unlimited amount of threads. In case I reached the limit of the threads (e.g. 100), I want the server to fallback to 'sychronous' mode (no parallelism). See the ThreadPoolExecutor.CallerRunsPolicy.
Background (read only in case you are interested in my motivation):
We have a project which relies on usage of ThreadLocals (e.g. we use Spring and its SecurityContextHolder). We would like to make 10 calls to backend systems in parallel. We like the ThreadPoolExecutor.CallerRunsPolicy, which runs the callable in the caller thread in case thread pool and its task queue is full. That's why we would like to use ThreadPoolExecutor. I am not able to change the project not to use ThreadLocals, please do not suggest doing so.
I was thinking how to do it with the least amount of work. SecurityContextHolder can be switched to use InheritableThreadLocal instead of ThreadLocal. The thread-local variables are then passed to child threads when the child threads are created. The only problem is how to make ThreadPoolExecutor create new Thread for every task. Will setting its keepAliveTime and corePoolSize to 0 work? Am I sure none of the threads will be reused for a next task? I can live with performance hit of creating new Threads, because the parallel tasks take much more time each.
Other possible solutions considered:
Extend ThreadPoolExecutor's execute method and wrap the Runnable command parameter into a different Runnable which remembers thread-locals into its final fields and then initializes them in its run method before calling the target command. I think this might work, but it is sligtly more code to maintain than the solution my original question is about.
Pass thread-locals in a parameter of asynchronous methods. This is more verbose to use. Also people can forget to do it, and the security context would be shared between asynchronous tasks :-(
Extend ThreadPoolExecutor's beforeExecute and afterExecute methods and copy thread-locals using reflection. This requires ~50 lines of ugly reflection code and I am not sure how safe it is.
Nope, this does not work! ThreadPoolExecutor wraps your Callable/Runnable into an internal Worker object and executes it in its runWorker() method. The Javadoc of this method says:
Main worker run loop. Repeatedly gets tasks from queue and executes them, while coping with a number of issues: ...
You can also take a look at the code of this method and see that it does not exit until the task queue is empty (or something bad happens which causes the thread to exit).
So setting keepAliveTime to 0 will not necessarily cause a new thread on each submitted task.
You should probably go with your solution 3 as the beforeExecute() and afterExecute() methods are exactly meant for dealing with ThreadLocals.
Alternatively, if you insist of having new threads for each task, you may take a look at Spring's SimpleAsyncTaskExecutor. It guarantees you a new thread for each task and allows you to set a concurrency limit, i.e. the equivalent of ThreadPoolExecutor#maxPoolSize.

Difference between ForkJoinPool and normal ExecutionService?

I read a great article about the fork-join framework in Java 7, and the idea is that, with ForkJoinPool and ForkJoinTask, the threads in the pool can get the sub tasks from other tasks, so it's able to use less threads to handle more tasks.
Then I tried to use a normal ExecutorService to do the same work, and found I can't tell the difference, since when I submit a new task to the pool, the task will be run on another available thread.
The only difference I can tell is if I use ForkJoinPool, I don't need to pass the pool to the tasks, because I can call task.fork() to make it running on another thread. But with normal ExecutorService, I have to pass the pool to the task, or make it a static, so inside the task, I can call pool.submit(newTask)
Do I miss something?
(You can view the living code from https://github.com/freewind/fork-join-test/tree/master/src)
Although ForkJoinPool implements ExecutorService, it is conceptionally different from 'normal' executors.
You can easily see the difference if your tasks spawn more tasks and wait for them to complete, e.g. by calling
executor.invoke(new Task()); // blocks this thread until new task completes
In a normal executor service, waiting for other tasks to complete will block the current thread. There are two possible outcomes: If your executor service has a fixed number of threads, it might deadlock if the last running thread waits for another task to complete. If your executor dynamically creates new threads on demand, the number of threads might explode and you end up having thousands of threads which might cause starvation.
In opposite, the fork/join framework reuses the thread in the meantime to execute other tasks, so it won't deadlock although the number of threads is fixed:
new MyForkJoinTask().invoke();
So if you have a problem that you can solve recursively, think of using a ForkJoinPool as you can easily implement one level of recursion as ForkJoinTask.
Just check the number of running threads in your examples.

Java thread pool blocking queue, execute always last few

I have several tasks that are being created by some event. I want to execute the last few tasks(suppose 6) always.
I am using a fixed thread pool. But the problem I am facing is that, it uses a blocking queue internally. I want to dequeue the tasks from the blocking queue if there are new tasks coming in, without pushing them to the executor. How can I achieve this? Is there a different approach to this problem?
In order to do what you want, you can use a ScheduledThreadPoolExecutor. And set the flag setRemoveOnCancelPolicy(true).
This executor returns a Future when you call the submit methods. These futures have a cancel() method that you can call when the new request comes in. You can even cancel the tasks that are currently running if you want too.
There's another alternative to call ThreadPoolExecutor.getQueue().clear(), but this is not safe! So please don't try it :)

thread pool - make a new one per task, detect when a set of tasks is done

Running concurrent tasks via ThreadPoolExecutors. Since I have 2-3 sets of tasks to do, for now have a map of ThreadPoolExecutors and can send a set of tasks to one of them.
Now want to know when a pool has completed all tasks assigned to it. The way its organized is that I know before hand the list of tasks, so send them to a newly constructed pool, then plan to start pooling/ tracking to know when all are done.
One way would be to have another pool with 1-2 threads, that polls the other pools to know when their queues are empty. If a few scans show them as empty (with a second sleep between polling, assumes they are done).
Another way would be to sub class ThreadPoolExecutor , keep a track via the queue and over ridding afterExecute(Runnable r, Throwable t) so can know exactly when each task is done, good to show status and know when all are complete if everything moving smoothly.
Is there an implementation of the second some where? Would be good to have an interface that listeners can implement, then add them selves to the sub classed method.
Also looking for an implementation :
To to ask a pool to shut down within a time out,
If after a time out the shut down is not complete then call shutdownNow()
And if this fails then get the thread factory and stop all threads in its group. (assumes that we set the factory and it uses a group or other way to get a reference to all its threads)
Basically as sure a way as we can, to clean up a pool so that we can have this running in an app container. Some of the tasks call selenium etc so there can be hung threads.
The last ditch would be to restart the container (tomcat/jboss) but want that to be the last ditch.
Question is - know of an open source implementation of this or any code to start off with?
For your first question, you can use a ExecutorCompletionService. It will add all completed tasks into a Queue so with a blocking queue you can wait until all tasks arrived at the queue.
Or create a subclass of FutureTask and override its done method to define the “after execute” action. Then submit instances of this class wrapping your jobs to the executor.
The second question has a straightforward solution. “shut down within a time out, and if after a time out the shut down is not complete then call shutdownNow()”:
executor.shutDown();
if(!executor.awaitTermination(timeout, timeUnit))
executor.shutdownNow();
Stopping threads is something you shouldn’t do (Thread.stop is deprecated for a good reason). But you may invoke cancel(true) on your jobs. That could accelerate the termination if your tasks support interruption.
By the way it looks very unnatural to me having multiple ThreadPoolExecutors and playing around with shutting them down instead of simply having one ThreadPoolExecutor for all jobs and letting that ThreadPoolExecutor manage the live cycle of all threads. That’s what the ThreadPoolExecutor is made for.

java executor with pre-emptable thread queue

I'm looking for a java thread-pool, that won't run more threads simultaneously than there are cores in the system. This service is normally provided by a ThreadPoolExecutor using a BlockingQueue.
However, if a new thread is scheduled to execute, I want the new thread to pre-empt one of the already running threads, and add the the pre-empted thread (in a suspended state) to a task queue, so it can be resumed as soon as the new thread is finished.
Any suggestions?
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.
The idea of a ThreadPoolExecutor is to avoid all of the expensive actions related to creating and destroying a thread. If you absolutely insist on preempting the running tasks, then you won't get that from the default API.
If you are willing to allow the running tasks to complete and instead only preempt the tasks which have not begun execution, then you can use a BlockingQueue implementation which works like a Stack (LIFO).
You can also have tasks 'preempt' other tasks by using different executors with different thread priorities. Essentially, if the OS supports time-slicing, then the higher priority executor gets the time-slice.
Otherwise, you need a custom implementation which manages execution. You could use a SynchronousQueue and have P worker threads waiting on it. If a client calls execute and SynchronousQueue.offer fails, then you would have to create a special worker Thread which grabs one of the other Threads and flags them to halt before executing and again flags them to resume after executing.

Categories