java執行緒阻塞喚醒、interrupt測試
阿新 • • 發佈:2019-02-05
執行緒阻塞可以採用Object.wait()、Object.notify()來控制執行緒的阻塞喚醒。
另一種方式是呼叫Unsafe.park()、Unsafe.unpark()。
在主動呼叫執行緒interrupt方法之後,目標執行緒如果正在block狀態就會被喚醒,通過Object.wait()、Unsafe.park()控制的阻塞都會被喚醒並直接往下執行,但是如果執行後面的邏輯中再次碰到Object.wait()就會再次被阻塞,而如果是碰到Unsafe.park()執行緒則會直接往下執行。測試程式碼如下
public class InterruptTest { public static void main(String[] args) { String t1b = "t1 block"; final Thread t1 = new Thread(()->{ StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10000000; i++) { sb.append(i ^ 100); } try { synchronized (t1b) { t1b.wait(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(1); LockSupport.park(t1b);//park 線上程被標識為interrupt之後會直接往下執行 //Object.wait() 線上程標識為interrupt之後還是會阻塞 try { synchronized (t1b) { t1b.wait(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(2); }); t1.start(); // try { // Thread.sleep(500); // } catch (InterruptedException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } //執行緒如果正在wait、sleep中會直接丟擲一個InterruptedException異常並且往下執行,如果再次碰到wait、sleep那還是會被阻塞 //執行緒如果是RUNNING狀態,之後第一次遇到wait或者sleep也會丟擲InterruptedException異常並且往下執行,但是再次遇到wait、sleep時還是會被阻塞 //如果是park則都會直接跳過並且不丟擲異常 t1.interrupt(); }