01: package snow.concurrent;
02:
03: import java.util.concurrent.*;
04: import java.util.*;
05:
06: /** wraps a runnable into an interruptable task.
07: I.e. creates a thread that can be interrupted.
08: should only be interrupted when not stopping itself correctely with the Interrupter
09:
10: Usage example
11:
12: InterruptableTask actualTask = new InterruptableTask()
13: {
14: public void run()
15: {
16: ...
17: if(interrupter.getShouldStopEvaluation()) return;
18: }
19: };
20: Thread t = new Thread(actualTask);
21: t.setPriority(Thread.MIN_PRIORITY);
22: t.start();
23: */
24: public abstract class InterruptableTask<T> implements Callable<T>,
25: Runnable {
26: Thread thread;
27: final public Interrupter interrupter = new Interrupter(); // correct way to stop the thread
28: Future future; // set at submit
29: private boolean isExecuting = false;
30:
31: public InterruptableTask() {
32: }
33:
34: public boolean isExecuting() {
35: return isExecuting;
36: }
37:
38: /** creates a thread to evaluate this task and Waits until completion, returning null
39: */
40: public final T call() throws Exception {
41: if (this .interrupter.getShouldStopEvaluation()) {
42: // never evaluates !
43: return null;
44: }
45:
46: isExecuting = true;
47: thread = new Thread(this );
48: // wait until completion
49: try {
50: thread.start();
51: thread.join();
52: } catch (Exception e) {
53: kill();
54: throw e;
55: } finally {
56: isExecuting = false;
57: }
58: return null;
59: }
60:
61: /** use only if request stop has not succeded.
62: This kills the thread.
63: BE CAREFUL: if the therad calls EventQueue.invokeAndWait, and catch Exception without throwing them
64: the thread continues !!
65: */
66: public void kill() {
67: if (thread != null && thread.isAlive()) {
68: thread.interrupt(); // throws an exception that may be catched => not 100% stops
69: }
70:
71: // thread.stop() // stops 100% but not safe ! deprecated !!
72: }
73:
74: public void requestStop() {
75: if (interrupter.getShouldStopEvaluation()) {
76: // already cool stopped but still called => kill
77: kill();
78: } else {
79: // first attempt : cool stop
80: interrupter.stopEvaluation();
81: }
82: }
83:
84: }
|