Java併發原理學習筆記+總結+實戰(5)——Lock接口

一、

    在JDK1.5之後,在java.util.concurrent.locks的包中提供了另一種實現代碼同步的方法,Lock。

    在前面說過,synchronize鎖是一種重量級的,特別耗費資源的鎖。在使用synchronize中,當線程被阻塞或等待處理,但又沒有釋放鎖時,其他線程只能在外面等待,非常影響執行效率。這就需要有一種機制可以不讓等待的線程一直無期限地等待下去(比如只等待一定的時間或者能夠響應中斷),通過Lock就可以辦到。

    但是需要注意:

    1)Lock需要顯示地獲取和釋放鎖,繁瑣能讓代碼更靈活

    2)Synchronized不需要顯示地獲取和釋放鎖,簡單

二、

查看Lock的源碼可以看到,Lock接口主要有這幾個方法:

                              

其中,lock()、lockInterruptibly()、tryLock()和tryLock(long time, TimeUnit unit)是用來獲取鎖的,unlock()是用來釋放鎖的。

2.1 lock()

    lock()方式是最常用的獲取鎖的方法。如果當時鎖不可用(被其他線程佔用)則線程等待。由於lock是不會主動釋放鎖的,爲了防止出現死鎖的情況發生,lock()代碼塊必須進行異常捕捉與處理,並在finally中調用unlock()方法來保證鎖的釋放。

  private int value;
  Lock lock = new ReentrantLock();
  public int getNext() {
    lock.lock();
    int a = 0;
    try {
      a = value++;
    } catch (Exception e) {
      e.printStackTrace();
    }finally {
      lock.unlock();
    }
    return a;
  }

2.2 lockInterruptibly()

    當通過該方法獲取鎖時,如果鎖可用,則獲取鎖;如果鎖不可用,則當前線程進入等待(休眠)狀態,直到發生以下情況:

     1)、對該等待線程調用interrupt()方法,中斷該線程等待狀態

     2)、如果當前線程在進入該方法前就調用interrupt()方法,即被設置爲中斷狀態,或者在獲取鎖定時被中斷,則會拋出InterruptedException異常,然後清除中斷狀態。

注意:當線程成功獲取到鎖之後是無法調用interrupt()方法中斷的。因爲interrupt()方法只能中斷被阻塞過程中的線程。

2.3 tryLock()

    tryLock()方法是一個返回布爾值的方法,表示在能成功獲取到鎖時返回true;不能獲取到鎖返回false。該方法在無論能否成功獲取到鎖時都會及時的返回,而不會在不能獲取到鎖時等待。

Lock lock = ...;
if (lock.tryLock()) {
   try {
    // manipulate protected state
  } finally {
    lock.unlock();
  }
 } else {
  // perform alternative actions
 }
}

2.4 tryLock(long time, TimeUnit unit)

    tryLock(long time, TimeUnit unit)和tryLock()類似,只是多了兩個參數:

    ·time : 最長等待解鎖時間

    ·unit  : 時間單位

    該方法在調用時需要傳遞等待時間和單位,在等待時間內無法獲取到鎖則返回false,否則則返回true

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章