2

Basically I have the following snippet,


(let [task (FutureTask. fn)
      thr (Thread. task)]
  (.start thr)
  ;;wait for signal...
  (.cancel task true)
  (.stop thr))

Problem is once in a while cancel does not work, AFAICT cancel causes and exception to be thrown but some piece of code down the line catches it? Is there a sure way to cancel a future task?

fn is a function that basically does a series of long running calculations so I can't loop checking for a boolean flag.

Hamza Yerlikaya
  • 49,047
  • 44
  • 147
  • 241

3 Answers3

6

There is no way to stop a running task automatically in Java - in the general case it is not safe to simply "kill" an executing thread, as doing so could leave things in an inconsistent state. As a result, this ability was intentionally left out Java.

When you cancel a task, a flag is set in the executing thread, but no exception is thrown. In order to allow a task to be cancelled, you will have to write code to periodically check if the thread has been interrupted:

while (notDone) {
    if (Thread.isInterrupted()){
      return; // we were cancelled (or interrupted in some other way)
    }

    doSomeHardWork()
}
nerdytenor
  • 431
  • 2
  • 7
1

According to my (limited) knowledge, there is no general method to do that. It's because you could have one uninterruptible, remote task, you could have one task which is pure function and thus safe to kill, you could have many subtasks (as nerdytenor mentioned -- check for isInterrupted state between each), you could have mix of everything, you could have task that when killed would put other tasks in global lock state... So as far as I know you have to do it yourself.

What kind of calculations do you perform? Can you do anything inside? Maybe create some global, thread-safe table toInterrupt and check in each subtask if the whole task is about to be cancelled? I know this is very non-idiomatic but can't think of anything better for now.

Or if those are really pure-functional calculations and you are really certain about that -- kill process/thread and hope you were right.

kgadek
  • 1,446
  • 1
  • 17
  • 18
0

This question probably is related Executing a function with a timeout

The macro works for my code, the thunk-timeout code is here

(defmacro with-timeout [time & body]
  `(thunk-timeout (fn [] ~@body) ~time))
Community
  • 1
  • 1
Kevin Zhu
  • 2,746
  • 26
  • 23