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...
Related
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.
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 :)
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.
This question is Related to List returned from shutdownNow() can not be converted to submitted Runnable
Problem definition
I want to get runtime exception from Runnableand which I can get only using submit() call which returns me Future<?>.
If I use Submit I loose on the functionality which is provided by execute. As I will no longer able to use shutdownNow() to track not started threads.
So Is this true
If I want to catch runnable exception from my task I will never be able to use shutdownnow to find out not started task.
You can use execute() together with Future by using a custom subclass of FutureTask (which is a Runnable). for most Executors, calling submit() just wraps the Runnable/Callable with a FutureTask under the hood. In you custom subclass of FutureTask, keep a reference to the underlying Runnable/Callable and expose a method for returning it. then, when you call shutdownNow(), the returned Runnables should be instances of your custom FutureTask. (it's annoyting that you need to subclass FutureTask to be able to get at the underlying task, but that's the way it is).
In my Callable code I use signaling to notify multiple ending behaviours to another thread. The Callable objects are queued up with FutureTasks in an Executor. They may also be cancelled after being queued up.
Now, my problem is that I rely on the tasks atleast being started for my signaling to work, but it looks like the Executor just skips a task if it's been marked as canceled before it got a chance to run it.
So, is there a way to garantee that a task is always started, and always cancelled (by InterruptedException) while running.
Also, can you check if a task has not started but failed?
You can probably subclass FutureTask class and override its done() method to perform the signalling. According to the documentation, this method should be called even if the task has been cancelled.