溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

java并發(fā)編程之Lock是什么

發(fā)布時(shí)間:2020-07-01 09:27:42 來(lái)源:億速云 閱讀:173 作者:清晨 欄目:開(kāi)發(fā)技術(shù)

這篇文章將為大家詳細(xì)講解有關(guān)java并發(fā)編程之Lock是什么,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

首先我們來(lái)回憶一下上一節(jié)講過(guò)的synchronized關(guān)鍵字,該關(guān)鍵字用于給代碼段或方法加鎖,使得某一時(shí)刻它修飾的方法或代碼段只能被一個(gè)線程訪問(wèn)。那么試想,當(dāng)我們遇到這樣的情況:當(dāng)synchronized修飾的方法或代碼段因?yàn)槟撤N原因(IO異?;蚴莝leep方法)被阻塞了,但是鎖有沒(méi)有被釋放,那么其他線程除了等待以外什么事都做不了。當(dāng)我們遇到這種情況該怎么辦呢?我們今天講到的Lock鎖將有機(jī)會(huì)為此行使他的職責(zé)。

1.為什么需要Lock

synchronized 是Java 語(yǔ)言層面的,是內(nèi)置的關(guān)鍵字;Lock 則是JDK 5 的J.U.C(java/util/currrent)包中出現(xiàn)的一個(gè)類,在使用時(shí),synchronized 同步的代碼塊可以由JVM自動(dòng)釋放;Lock 需要程序員在finally塊中手工釋放;synchronized是比較古老的實(shí)現(xiàn)機(jī)制,設(shè)計(jì)較早,有一些功能上的限制:

——它無(wú)法中斷一個(gè)正在等候獲得鎖的線程

——也無(wú)法通過(guò)投票得到鎖,如果不想等下去,也就沒(méi)法得到鎖。

——同步還要求鎖的釋放只能在與獲得鎖所在的堆棧幀相同的堆棧幀中進(jìn)行

而且對(duì)多線程環(huán)境中,使用synchronized后,線程要么獲得鎖,執(zhí)行相應(yīng)的代碼,要么無(wú)法獲得鎖處于等待狀態(tài),對(duì)于鎖的處理不靈活。而Lock提供了多種基于鎖的處理機(jī)制,比如:

  1. void lock(),獲取一個(gè)鎖,如果鎖當(dāng)前被其他線程獲得,當(dāng)前的線程將被休眠。
  2. boolean tryLock(),嘗試獲取一個(gè)鎖,如果當(dāng)前鎖被其他線程持有,則返回false,不會(huì)使當(dāng)前線程休眠。
  3. boolean tryLock(long timeout,TimeUnit unit),如果獲取了鎖定立即返回true,如果別的線程正持有鎖,會(huì)等待參數(shù)給定的時(shí)間,在等待的過(guò)程中,如果獲取了鎖定,就返回true,如果等待超時(shí),返回false。
  4. void lockInterruptibly(),如果獲取了鎖定立即返回,如果沒(méi)有獲取鎖定,當(dāng)前線程處于休眠狀態(tài),直到或者鎖定,或者當(dāng)前線程被別的線程中斷。
     

可見(jiàn)lock比synchronized提供了更細(xì)的粒度、更靈活的控制。

2.初探Lock

在jdk1.5之后,并發(fā)包中新增了Lock接口(以及相關(guān)實(shí)現(xiàn)類)用來(lái)實(shí)現(xiàn)鎖功能,其實(shí)真正的實(shí)現(xiàn)Lock接口的類就三個(gè),ReentrantLock和ReentrantReadWriteLock的兩個(gè)內(nèi)部類(ReadLock和WriteLock實(shí)現(xiàn)了Lock的接口),下面我們來(lái)看一下Lock的類圖:

java并發(fā)編程之Lock是什么

  • ReentrantLock:一個(gè)可重入的互斥鎖,為lock接口的主要實(shí)現(xiàn)。
  • ReentrantReadWriteLock:
  • ReadWriteLock、ReadWriteLock 維護(hù)了一對(duì)相關(guān)的鎖,一個(gè)用于只讀操作,另一個(gè)用于寫(xiě)入操作。
  • Semaphore:一個(gè)計(jì)數(shù)信號(hào)量。
  • Condition:鎖的關(guān)聯(lián)條件,目的是允許線程獲取鎖并且查看等待的某一個(gè)條件是否滿足。
  • CyclicBarrier:一個(gè)同步輔助類,它允許一組線程互相等待,直到到達(dá)某個(gè)公共屏障點(diǎn)。

①首先我們來(lái)看一下Lock的用法:

  Lock lock = new ReentrantLock();
  lock.lock();
  try{
  //處理任務(wù)
  }catch(Exception ex){

  }finally{
  lock.unlock();  //釋放鎖
  }

正常使用Lock的用法最多就是這樣,ReentrantLock是Lock的實(shí)現(xiàn)類們也是最常使用的。如果采用Lock,必須主動(dòng)去釋放鎖,并且在發(fā)生異常時(shí),不會(huì)自動(dòng)釋放鎖。因此一般來(lái)說(shuō),使用Lock必須在try{}catch{}塊中進(jìn)行,并在finally塊釋放鎖,以保證鎖一定被被釋放,防止死鎖的發(fā)生。

②我們也可以這樣使用Lock:

Lock lock = new ReentrantLock();
  if(lock.tryLock()) {
     try{
       //處理任務(wù)
     }catch(Exception ex){

     }finally{
       lock.unlock();  //釋放鎖
     } 
  }else {
    //如果不能獲取鎖,則直接做其他事情  
  }

tryLock()方法是有返回值的,它表示用來(lái)嘗試獲取鎖,如果獲取成功,則返回true,如果獲取失敗(即鎖已被其他線程獲?。﹦t返回false,也就說(shuō)這個(gè)方法無(wú)論如何都會(huì)立即返回。在拿不到鎖時(shí)不會(huì)一直在那等待。

關(guān)于java并發(fā)編程之Lock是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI