文章出處
View Code
文章列表
線程狀態
新建狀態
線程被創建時,會短暫的處于這種狀態。處于這種狀態的線程已經分配了必須的系統資源,有資格獲得cpu時間了,等待調度器把它轉變為可運行狀態或阻塞狀態;
就緒狀態
在這種狀態下,只要調度器把時間片分配給線程,就可以馬上運行;
阻塞狀態
線程因為某個條件未滿足,阻止了它的運行;這種狀態會被調度器忽略,直到條件滿足時,轉為就緒狀態;
死亡狀態
線程運行結束或被中斷后的狀態;該狀態不能被調度,不會分配cpu時間;
線程進入阻塞狀態的方式
- 調用sleep方法
- 調用wait方法
- 任務等待某個輸入輸出完成
- 調用其它同步控制方法,等待其它線程釋放鎖
線程中斷
線程阻塞及中斷
先看一段代碼,如下:

package concurrency; import java.util.concurrent.*; import java.io.*; class SleepBlocked implements Runnable { public void run() { try { TimeUnit.SECONDS.sleep(100); } catch (InterruptedException e) { System.out.println("InterruptedException"); } System.out.println("Exiting SleepBlocked.run()"); } } class IOBlocked implements Runnable { private InputStream in; public IOBlocked(InputStream is) { in = is; } public void run() { try { System.out.println("Waiting for read():"); in.read(); } catch (IOException e) { if (Thread.currentThread().isInterrupted()) { System.out.println("Interrupted from blocked I/O"); } else { throw new RuntimeException(e); } } System.out.println("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() { f(); // Lock acquired by this thread } }.start(); } public void run() { System.out.println("Trying to call f()"); f(); System.out.println("Exiting SynchronizedBlocked.run()"); } } public class Interrupting { private static ExecutorService exec = Executors.newCachedThreadPool(); static void test(Runnable r) throws InterruptedException { Future<?> f = exec.submit(r); TimeUnit.MILLISECONDS.sleep(100); System.out.println("Interrupting " + r.getClass().getName()); f.cancel(true); // Interrupts if running System.out.println("Interrupt 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.println("Aborting with System.exit(0)"); System.exit(0); // ... since last 2 interrupts failed } }
以上代碼中,展示了三種進入阻塞狀態的情景:調用sleep方法,等待io,等待其它線程釋放鎖;
以及嘗試調用Future的cancel方法去中斷阻塞的線程,從運行結果可以發現,只有sleep可以被中斷,其它等待io和等待鎖釋放都不能被中斷;這一點也可以從sleep方法會拋出InterruptedException異常看出來,其它兩個不會拋出該異常;
那么對于io阻塞和互斥鎖阻塞的線程如何中斷?
中斷io阻塞
方式一,調用shutdownNow關閉線程池,調用close方法關閉IO流資源;
方式二,使用nio
中斷互斥鎖阻塞
使用并發庫中的ReentrantLock鎖;
ps:如果是同一個線程的話,是可以調用在同一個對象中的其它synchronized方法;
檢查中斷
調用Thread.interrupted(),查看interrupt()是否調用過,并清除中斷狀態,避免中斷被通知兩次;
文章列表
全站熱搜