How to reactive a cancelled futuretask in thread pool? - java

I use ThreadPoolExecutor to run some actions, at some time I cancelled some future tasks and stored it into a list to arrange some other tasks to do, and after that I want to reactive the saved cancelled future tasks.
But the problem is when I submit the task into the pool, it would not be executed, looks like the cancelled or done flag is saved and recognized by the thread executor, and thus that thread would not be called.
What should I do?

The FutureTask implementation maintains the canceled state. Essentially, when the run() method is called again, it does a CAS operation which fails since the state is not runnable and returns immediately without invoking the inner Callable's call() method. I couldn't see a way to retrieve the original Callable out of it or restore the FutureTask to a non-canceled state.
In response to what should you do...
Do you have to cancel them? Why not let them run? If you want priority execution, could you try creating your ThreadPoolexecutor with a PriorityBlockingQueue and use a Comparator to establish the priority. This will allow tasks to be executed in the proper order since they will be added to the PriorityBlockingQueue based on the results of the Comparator.

Use Runnable instead of threads. The execution pool can handle a Runnable the same way a Thread, but a Runnable could be rerunned number of times.

If you want to have a return value you can use a Callable. http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html

Related

Ensure unique tasks in ExectorService

I have a scenario wherein same Tasks get assigned multiple times to an ExecutorService. I want to avoid that, Is there a way to do it?
I have Tasks with a String constructor.
Task task1 = new Task ("A");
than I execute this task
executor.execute (task1);
Then I create another task with same string.
Task task2 = new Task ("A");
Lets say I cannot avoid this from happening.
Now I execute this task.
executor.execute (task2).
I want only one of these tasks to be executed, since both tasks are similar in nature.
How?
At first, I would have implemented a queue interface and passed it to the executor service. My implementation would be using a hashset to hold the memory, next to a regular collection to hold the tasks as the queue requires. Adding to my queue therefore would have involved checking the hashset first. Maybe a linkedhashset rolling off eldest entries...
However, the executorservice submit() doesn't fully rely on the queue. See the javadoc of ThreadPoolExecutor. The queue could refuse the task, but the executor could spawn a thread instead and still accept the task. Besides, that implies you could intervene in the executor's construction anyway.
So, presuming control on the executor's class, it seems you must extend an executorservice and have the knowledge there instead of a in a custom queue. You only need to override submit() and throw the rejection exception.
Of course, this reveals the rejection to the submitter. You should deal with that gracefully. You cannot hide this fact because you cannot return a Future if there was no submission. Unless you wire up the old Future to the new one (your knowledge hashmap contains Futures). This may cause difficulties though since every Future has a 'done' state and is cancel-able... Your own Future would be delegating to the original Futures. I think task rejection is simpler.

Telling the asynchronous job to wait in Java

I have a situation where sometimes (not always) my asynchronous job is not able to process results by the time needed and I have to return some kind of message to the client saying that his request is still being prepared by checking for it in the database.
The request and creating necessary object for it is handled in one database Transaction, the asynchronous process is handled in the different Transaction. I am using ScheduledThreadPoolExecutor by passing the runnable instance to the execute method.
The problems that sometimes the client makes a request and while the his browser is loading my asynchronous job is able to prepare the necessary data for it, but sometimes it isn't.
So my question is: Is there anyway I can tell asynchronous job to wait until the data is ready?
I am afraid that using just a Runnable instance you are not be able to tell the process to wait unless you sleep the Thread for sometime or looping and keep asking for the results which both are bad ideas.
In order to make this happen correctly, you should use a FutureTask for this by passing Callable instance to it's constructor. By overriding your call() method you should tell you transactional handler to do the job.
You also need to have some kind of a task manager which will add the task to the queue and creates a thread pool which takes and processes those tasks. For the queue purpose I would suggest to use for e.g.: LinkedBlockingDeque which accepts the generic type of FutureTask.
Also you should have a map of future tasks mapped by their name or something which takes the FutureTask as a value. In terms of waiting for the results when your Thread is processed the given FutureTask already you have to immediately remove it from the futures map. Then when your client requests you should check: if the futures map contains the task get the FutureTask from it and call futureTask.get() on it. This will wait until the task is finished.
This is just approach with which I would go. Hope this helps.

Java: ExecutorService with Callables: Reuse the same Pool in a loop? Shutdown necessary?

I got a loop {Loop-1}, where I start Threads. The class which contains the {Loop-1} implements Daemon and Runnable.
In the {Loop-1} the thread, which is started, calls a method coordinate() of a class Coordinate.java where I use the ExecutorService.
When the object of Coordinate.java is created (this happens once BEFORE {Loop-1}), I instantiate a ExecutorService
pool = Executors.newFixedThreadPool(2);
In coordinate() I create two Objects of a class which implements Callable and I start them then and store the result in a List of Future results.
callableResults = pool.invokeAll(threads);
After, I try to get the results in a loop with result = future.get();
Then, I return to {Loop-1} and the whole process starts again (call coordinate(), invokeAll(), future.get()
Now Ive got the following question:
1. Do I need to shutdown the pool of ExecutorService after I got the results in coordinate()?
2. Do I need to recreate the pool everytime my {Loop-1} calls coordinate()?
Thanks for answers! :-)
No you do not. The threads in the fixed thread pool can be used until you call shutdown on it. So, you can simply resubmit new tasks to be executed and fetch their results, exactly as you did in the first go-round.
You need to shutdown the executorService once you're done processing all your tasks.
The submission of tasks can be in multiple cycles.
Once you call executorService.shutDown(), you can wait until all tasks are completed after calling shutDown() using executorService.awaitTermination(10, TimeUnit.SECONDS).
Alternatively, you can do: while (!executorService.isTerminated()) { }

Should I call cancel(true) on Future<?> or my own FutureTask

I have a custom class MyFutureTask extends FutureTask<Void> upon which I do some code on the done() method.
I use an ExecutorService which I call submit(new MyFutureTask()) into it.
Now I can keep a reference to the Future<?> that gets returned after you call submit, but when I call cancel to that the isCancelled() method never returns true.
Should I ignore the Future<?> object that gets returned and instead work with MyFutureTask and call cancel(true) on that instead?
What is the use of the Future<?> object then?
edit: What's the difference between Future and FutureTask in Java? from this thread I understand the difference.
Besides the default cancel behavior I also want to attempt to stop a network call in progress so I guess the route I am going to use FutureTask is correct. Someone can confirm?
Don't use Executor.submit, instead use Executor.execute since you already have a Future. When you call submit, you are just needlessly wrapping your FutureTask in another FutureTask.
Also you can't "stop" a network trip. You have to wait until it returns or times out. What you do is call Future.cancel(true), then when your network trip returns look and see if the future has been canceled Future.isCancelled(). THen you can just stop doing what you were doing in the Future. For all intents and purposes it's the same effect as if you could cancel a network trip. To the end user (ie the client code or caller) it will appear the same way. The only side effect you might notice is if you have only a single thread executing tasks in which case the thread waiting on the network trip has to return before it will pick up the next task. If that's a problem using a pool of threads.
As an aside if you used NIO or some library thereof you could stop waiting on the result immediately, but that's a lot more work to code up.

JAVA - Cancel the ThreadPoolExecutor running tasks

What I need is a method similar to shutdownNow, but, be able to submit new tasks after that. My ThreadPoolExecutor will be accepting a random number of tasks during my program execution.
You can grab the Future of each submission, store that Future in a collection, then when you want to cancel the tasks, invoke future.cancel() of all queued tasks.
With this solution the Exectuor is still running and any running tasks are cancelled or will not run if they are queued.
Why not create your own ExecutorService that exhibits this behaviour?
Is it not enough to just do getQueue() and clear it? If you really need to attempt to stop running tasks, you would need to subclass the ThreadPoolExecutor and essentially re-implement shutdownNow() but only copy the bit that sends an interrupt to each thread. Mind you this still isn't any guarantee that you will actually cause them to immediately cease and do no further calculation. You'll need a totally different approach if you need to do that.

Categories

Resources