Java thread pool blocking queue, execute always last few - java

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 :)

Related

Run parallel tasks in a long running application

I am building a long running application, which is modeled as a service based on service oriented architecture. Call this as 'serviceA'. It has an activity to perform, call 'activityA', whenever an API call is made to it.
activityA has an activity handler that has to perform 'n' tasks in parallel after which it consolidates and returns result to the client who called the serviceA API.
I am planning to use the ExecutorService to achieve this parallelism.
There are 2 ways to go ahead with this:
Create ExecutorService in a singleton scope, and have it as an attribute of the activity handler. Thus this same ExecutorService object is available throughout the lifetime of the service. When a new request comes, handler uses this ExecutorService object to submit parallel tasks. Then wait on the Future objects for certain timeout time. After all the parallel tasks complete, consolidate and return the activityA response.
Create new ExecutorService object everytime a request to activityA is received, in the activity handler. Submit the parallel tasks to this object, wait for the Future results for certain timeout time, consolidate the results, call shutdown on the ExecutorService object, and return the activityA API response.
Thus,
Which of the 2 above approaches should be followed? Major difference b/w the 2 is the lifetime of the ExecutorService object.
The service is supposed to be called with a volume of ~15k transactions per second, if this data helps with the decision making b/w the 2 approaches?
Advantage of 1st approach is that we will not have the overhead of creating and shutting down new ExecutorService objects, and threads. But, what happens when there is no Future result till the timeout time? Does the thread automatically shuts down? Is it available for any new request that will be coming to the ExecutorService thread pool? Or it will be in some waiting state, and eat up memory - in which case we manually need to do something (and what)?
Also, Timeout time while we call future.get() is from the time we make this get call or from the time we submitted the task to the executor service?
Please also let me know if any of the 2 way is the obvious approach to this problem.
Thanks.
The first way looks like the obvious and correct way to solve this problem, especially with the given amount of transactions. You certainly don't want to restart threads.
Future.get timeout doesn't affect the executing thread. It will continue to run the task until it is either completed or throws an exception. Until then, it won't be accepting new tasks (but other threads in the same executor will). In this case you may want to cancel it explicitly by invoking Future.cancel to free the thread for new tasks. This requires the task itself to respond properly to interrupt (instead of looping forever, for example, or waiting blocked on I/O). However, this would be the same for any threading approach since interruption is the only safe way to terminate a thread anyway. To mitigate this issue you could use a dynamic pool of threads with maximum number of running threads more than n. This will allow to process new tasks while the stuck tasks are in process of termination.
It's from the time you call 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.

Change queue size of a ThreadPoolExecutor

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.

ExecutorService-like class where user controls when Callables are called

I was using an ExecutorService to schedule tasks to be executed in future. After seeing some "odd" behavior where my Callable was getting executed before I called get() on the Future object returned by submitting my Callable to the ExecutorService pool, I read some documentation and found that the submitted task will get executed between the time it gets submitted or at the latest when get() is called on the Future object.
My question - is there any class that would allow Callables to be submitted to it and ONLY executed when get() is called on it? At this point, it seems like just managing the Callables myself and calling call() on them myself when I am ready for them to be executed seems like it'd accomplish what I want, but I wanted to make sure there was no service already implemented that accomplished this.
In short, is there any alternative to ExecutorService that lets me control when Callables submitted to it are called? Note - the time in the future that I want them called is variable and not determined as I may decide not to call them so a ScheduledExecutorService pool won't work here.
Thanks much!
Sounds like you really want to use a Queue<Callable> instead and just poll the queue for tasks.
That way you can submit as many tasks as you like and execute them at your will - one by one.

ExecutorService only run most recently added Callable

I have a single threaded executor service for fetching some data over the network.
As the user is typing in a search box I am enqueuing possible network tasks. What I want is to cancel all previous requests and only enqueue and immediately run the latest one.
My current approach is to override execute() and submit() methods and clear the queue before calling super.
Any thoughts on this?
Don't get it, why don't you save the Future returned on posting a callable to the service, and then cancel() the future if you don't want it to be executed.
e.g.
Future f1 = service.submit(some_task);
// later
f1.cancel(true); // will interrupt if running...
Cleaner IMO...

Categories