java.util.concurrent パッケージの使用を検討してください。作業ステップを Callable (または Runnable) としてラップする必要があります。
public class InterruptibleTest {
public static void main(String[] args) { try {
final ExecutorService queue = Executors.newFixedThreadPool(1);
queue.submit(new Callable<Void>() { @Override public Void call() { busyWait(1000); return null; } });
queue.submit(new Callable<Void>() { @Override public Void call() { busyWait(1000); return null; } });
queue.submit(new Callable<Void>() { @Override public Void call() { busyWait(1000); return null; } });
final AtomicBoolean cancelled = new AtomicBoolean();
new Thread() { @Override public void run() {
try { Thread.sleep(1500); } catch (InterruptedException ex) { }
queue.shutdownNow();
cancelled.set(true);
}
}.run();
if (cancelled.get()) { rollback(); }
queue.shutdown();
System.out.println("Finished");
} catch (Exception ex) { ex.printStackTrace(System.err); } }
public synchronized static void busyWait(int millis) {
System.out.println("Start");
long until = System.currentTimeMillis() + millis;
while (System.currentTimeMillis() < until) { }
System.out.println("Stopped");
}
public synchronized static void rollback() {
System.out.println("Rollback!");
}
}
shutdownNow() は、現在実行中の作業スレッドで interrupt() を呼び出す場合があることに注意してください。割り込み不可能なコードの実行が終了する前に shutdownNow() が戻るため、おそらく rollback() も同期する必要があります。