2

Recently I worked with ThreadPoolExecutor and priorityqueue and came across both methods future.cancel() on a future task. And task.remove() on the task it self, to remove it from the queue.

What is the better option? is there any difference? I can save list of both (the future object received from submit() or the tasks themselves), not sure what to use...

remove:

executor.remove(task);
executor.purge();

cancel:

futureObject.cancel(false);

I used the following: http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html#remove%28java.lang.Runnable%29

The false in the cancel is because I only want to remove a queue task, if it runs, let it finish.

sharon gur
  • 343
  • 5
  • 22

3 Answers3

3

Use Future.cancel()

The Javadoc for ThreadPoolExecutor.remove() states that it may "fail to remove tasks that have been converted into other forms before being placed on the internal queue", so I wouldn't recommend calling it unless you are sure the task wasn't converted internally.

Given that, if you have a Future, I would recommend canceling it by calling Future.cancel(). This has the added advantage of doing the right thing if someone else has a reference to the Future and decides to call Future.get()

If you are paranoid about the amount of heap used by the cancelled tasks, you can call ThreadPoolExecutor.purge() after calling Future.cancel().

By the way, the ThreadPoolExecutor.purge() method only removes Futures that have been canceled, so calling purge() after remove() is likely a no-op.

NamshubWriter
  • 23,549
  • 2
  • 41
  • 59
1

I would use the one which is more natural for you. Without further information that is most likely the cancel

remove/purge is much more expensive and only really needed if you are concerned you will have so many of these tasks they might be using too much memory.

The difference is pretty self explanatory, cancel just cancels the task. remove/purge removes the task from the queue.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • I am using a priorityQueue therefore I save a ComparableFutureTask as this suggests: http://stackoverflow.com/questions/30574777/implementing-priorityqueue-on-threadpoolexecutor I override the execute to return that ComparabaleFutureTask, and save all the referrences and on this object i preform the cancel(). and for some reason it doesnt work... I assume ill need to open a new question specific to that occurrence but is it suppose to work the same on a comparableFutureTask? Any – sharon gur Jun 03 '15 at 06:07
  • @sharongur what do you mean by; "it doesn't work" and what did you expect to happen? – Peter Lawrey Jun 03 '15 at 06:13
  • I cancel the task and reinsert a new one with higher priority, yet the execution order remains the same. and no new task inserted – sharon gur Jun 03 '15 at 06:15
  • @sharongur so the problem is to do with insertions not cancelling or removing? Ie not related to the question? – Peter Lawrey Jun 03 '15 at 06:24
  • I actually did exactly what the question I posted suggests, but when I added the cancel(); I didn't see any difference to when I didn't initiate that same method. Anyway I didnt investigated that enough to raise another question. Ill try to solved it myself and if I wont find a solution ill turn up here again :) thanks for the help! – sharon gur Jun 03 '15 at 06:25
  • @sharongur cancel just makes the task marked as "cancelled" and it won't run. It does this because this is more efficient than removing it from the data structure. However sometimes you really want it to go away which is why there is an option to remove it, even though it is slower, much slower in some cases. – Peter Lawrey Jun 03 '15 at 06:27
0

If you expect cancel to be overridden or your main concern is memory footprint then use remove/purge. But in any other case I would go for cancel.

JiriS
  • 6,870
  • 5
  • 31
  • 40