LockSupport使用

LockSupport功能

  1. LockSupport在JDK中主要提供了線程的阻塞和喚醒功能。提供了更高級別的同步功能。
  2. 阻塞方法主要是以park開頭的各種方法,喚醒線程的方法只有unpark一個方法。
  3. LockSupport中的 park和unpark方法提供的線程阻塞和喚醒功能,避免了Object中已經廢棄方法suspend和resume引起的死鎖問題。

阻塞方法

  1. park方法的執行與獲得的執行許可有關係。如果獲得許可,則調用park方法立即返回;如果沒有獲得許可,則調用park方法一直阻塞。默認情況下,調用park方法是沒有獲得許可的,即調用該方法要阻塞。
  2. park方法阻塞時,發生如下情況下可以就可解除阻塞
    2.1 其他線程調用該線程的unpark方法
    2.2 其他線程調用該線程的interrput方法,即park方法能夠響應中斷。
  3. LockSupport類中的park方法
// 阻塞當前線程
 public static void park()
// 在規定的納秒時間內阻塞狀態
 public static void parkNanos(long nanos) 
 // 在規定的毫秒時間內阻塞
 public static void parkUntil(long deadline)
 // 在規定的時間內阻塞與當前線程相關聯的對象
 public static void parkUntil(Object blocker, long deadline)
 // 阻塞與當前線程相關聯的對象
 public static void park(Object blocker) 

park

  1. 默認情況下,park方法獲取不到執行許可,執行該方法會一直阻塞
public class LockSupportService {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //LockSupport.unpark(Thread.currentThread());
        // 默認是被佔用的,會一直阻塞下去
        LockSupport.park();;
        System.out.println("aaaa");
    }
}

1.1. 如果上述程序中先調用LockSupport中的unpark方法,則park方法獲取到了許可,則不會阻塞。會立即返回。程序打印出aaaa。

unpark

  1. unpark(Thread thread)方法爲喚醒當前執行阻塞的線程。其方法參數就是指需要喚醒的線程對象。
  2. 結合park方法,瞭解一下LockSupport工具的使用。
public class LockSupportService {

    public static void main(String[] args) {
        // 釋放許可 
        LockSupport.unpark(Thread.currentThread());
        // 默認是被佔用的
        LockSupport.park();;
        System.out.println("aaaa");
        Thread ta = new Thread(new ServiceA());
        Thread tb = new Thread(new ServiceB(ta));    
        ta.start();
        tb.start();
    }

}
// 線程A
class ServiceA implements Runnable{
    public void run() { 
        LockSupport.park();
         System.out.println("I am  service A ");
    }
}
// 線程B
class ServiceB implements Runnable{
    private Thread thread;
    public ServiceB(Thread thread) {
        super();
        this.thread = thread;
    }

    public void run() {
        try {
            Thread.sleep(20*1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
         //thread.interrupt();
         // 喚醒當前阻塞的線程
         LockSupport.unpark(thread);;
         System.out.println("I am  service B "); 
    }
}
  1. 上述程序線程A調用park方法,默認情況下是沒有獲得許可,一直處於阻塞狀態。線程B睡眠20秒後,喚醒線程A。最終程序執行結果如下圖所示:
    這裏寫圖片描述
  2. 將線程B中的LockSupport中的unpark方法換成Thread.interrupt方法後,執行效果一樣,則證明了LockSupport中的park方法能夠響應線程的中斷。interrupt中斷當前線程的執行狀態。
    這裏寫圖片描述

總結

  1. LockSupport工具類在JDK中的併發處理中底層使用挺多的,多用心去理解和多看源碼有助於更深刻的瞭解。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章