這兩天看到好幾個關於可中斷線程的代碼分享,手癢癢,因而也寫一個玩玩。 java
package misty.thread.interruptable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; public class InterruptableThreadTest { public static class Task implements Runnable { @Override public void run() { try { while (!Thread.currentThread().isInterrupted()) { // Thread.interrupted()也能夠檢查中斷狀態是否被設置,可是它同時會清除中斷狀態。而isInterrupted不會。 // 處理業務邏輯 System.out.println("業務邏輯必須是可異步中斷的"); // 例如sleep就是可異步中斷的 TimeUnit.SECONDS.sleep(1); } } catch (InterruptedException e) { // 捕獲InterruptedException會清除中斷狀態 // 若是這個任務是在線程池中執行的,那麼應該將中斷狀態置回 Thread.currentThread().interrupt(); } // 線程結束 System.out.println("個人使命完成了"); } } /** * @param args * @throws InterruptedException * @throws ExecutionException */ public static void main(String[] args) throws InterruptedException, ExecutionException { // 方法1 Thread t = new Thread(new Task()); t.start(); TimeUnit.SECONDS.sleep(5); t.interrupt(); t.join(); // 方法2 ExecutorService exec = Executors.newCachedThreadPool(); Future<?> future = exec.submit(new Task()); TimeUnit.SECONDS.sleep(5); future.cancel(true); // 方法3 FutureTask<?> futureTask = new FutureTask<Void>(new Task(), null); exec.execute(futureTask); TimeUnit.SECONDS.sleep(5); futureTask.cancel(true); // 其實不管是哪一種,本質上都是Thread#interrupt exec.shutdown(); exec.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); } }固然這是最簡單的模擬。要想真正設計一個支持異步中斷的任務須要考慮不少問題。好比如何將一個大任務分解成若干小任務、任務在什麼位置容許中斷、必須用支持異步中斷的NIO來替換阻塞式的IO和Socket等。