import java.io.IOException; import java.io.InputStream; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; /** * Created by Administrator on 2017/10/12. */ class SleepBlocked implements Runnable { public void run() { try { TimeUnit.SECONDS.sleep(100); } catch (InterruptedException e) { System.out.print("\nInterruptedException"); } System.out.print("\nExiting SleepBlocked.run()"); } } class IOBlocked implements Runnable { private InputStream in; public IOBlocked(InputStream is) { in = is; } public void run() { try { System.out.print("\nwating for read()"); in.read(); } catch (IOException e) { if (Thread.currentThread().isInterrupted()) { System.out.print("\nInterruppted from blocked I/O"); } else { throw new RuntimeException(e); } } System.out.print("Exiting IOBlocked.run()"); } } class SynchronizedBlocked implements Runnable { public synchronized void f() { while (true)//never releases lock Thread.yield(); } public SynchronizedBlocked() { new Thread() { public void run() { System.out.print("\n構造函數trying to call f()"); f(); System.out.print("\n構造函數exiting trying to call f()"); } }.start(); } public void run() { System.out.print("\nRun() Trying to call f()"); f(); System.out.print("\nExiting SynchronizedBlocked.run()"); } } public class Interrupting { private static ExecutorService exec = Executors.newCachedThreadPool(); static void test(Runnable r) throws InterruptedException { Future<?> f = exec.submit(r); TimeUnit.MICROSECONDS.sleep(100); System.out.print("\nInterrupting " + r.getClass().getName()); f.cancel(true);//Interrupting if running System.out.print("\nInterrupted sent to " + r.getClass().getName()); } public static void main(String[] args) throws Exception { test(new SleepBlocked()); test(new IOBlocked(System.in)); test(new SynchronizedBlocked()); TimeUnit.SECONDS.sleep(3); System.out.print("\nAborting with System.exit(0)"); System.exit(0); } }
運行結果:java
Interrupting SleepBlocked
Interrupted sent to SleepBlocked
InterruptedException
Exiting SleepBlocked.run()
wating for read()
Interrupting IOBlocked
Interrupted sent to IOBlocked
構造函數trying to call f()
Run() Trying to call f()
Interrupting SynchronizedBlocked
Interrupted sent to SynchronizedBlocked
Aborting with System.exit(0)
Process finished with exit code 0函數
分析:線程
sleep()有一種狀況,將使任務從執行狀態變爲阻塞狀態,而有時必須終止將被阻塞的任務。調試
一個線程處於阻塞狀態時,調試器將不會分配給線程任何CPU時間,直到線程從新進入就緒狀態,它纔有可能從新獲取CPU。code
一個任務進入阻塞狀態,可能有以下緣由:對象
(1)經過調用sleep(milliseconds)使任務進行休眠狀態,在這種狀況下,任務在指定的時間內不會運行。get
(2)你經過調用wait()使線程掛起。直到線程獲得了notify()或notify all()消息(或者在JAVA SE5的java.util.concurrent類庫中等價的signal()或者signalall()消息),線程纔會進入就緒狀態。同步
(3)任務在等待某個輸入輸出完成 it
(4)任務試圖在某個對象上調用其同步控制方法,可是對象鎖不可用,由於另外一個任務已經獲取了這個鎖。io
如何主動停止阻塞狀態?
從以上三個示例能夠看出,中斷可以中斷對sleep()的調用(或者任何要求拋出InterruptedException的調用)。可是,你不能中斷正在試圖獲取synchronized鎖或者試圖執行I/O操做的線程。