3

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?

Community
  • 1
  • 1
dnkoutso
  • 6,041
  • 4
  • 37
  • 58

2 Answers2

0

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.

jtahlborn
  • 52,909
  • 5
  • 76
  • 118
  • Ah that makes sense, so I should not worry about the Future> object returned since I will use execute correct? And just work with my own FutureTask object to do cancel – dnkoutso Feb 13 '12 at 19:39
  • @dnkoutso - yes, it is completely superfluous (and misleading as you've seen), which is why i'd recommend not even using the submit method. – jtahlborn Feb 13 '12 at 19:44
0

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.

Aleksandr Dubinsky
  • 22,436
  • 15
  • 82
  • 99
chubbsondubs
  • 37,646
  • 24
  • 106
  • 138
  • actually, if you had a reference to the socket in-use in the Future's task, you _could_ call `close()` on it in a custom `cancel()` method implementation. (which would be a valid reason to write a custom FutureTask impl). – jtahlborn Feb 13 '12 at 19:46
  • I've done that thing exactly on my bitmap downloader where I cut a download while its in progress. I know its not guaranteed to stop a download in progress, thats why I also check the isCancelled() flag on the done() method afterwards... – dnkoutso Feb 13 '12 at 19:52
  • @chubbard Your response is also good and I would accept it, I only went to jtahl cause he came in first. Thank you really though. – dnkoutso Feb 13 '12 at 19:53
  • No jtalh had the right answer. Mine was an aside. Technically you can close the socket, but that assumes you have access to it. Most of time people aren't writing directly to sockets. They use some HTTP library that hides the socket. Socket.close() will just make the thread available faster. – chubbsondubs Feb 13 '12 at 19:57
  • I use HttpUrlConnection and I just call disconnect() on it. Sometimes I would see the stacktrace in the log :) p.s this is on Android. – dnkoutso Feb 13 '12 at 20:03