android 多線程 — reentrantLock 重入鎖

reentrantLock 踩窖、 condition 是 JAVA 1.6 時(shí)推出的势就,也是用來(lái)實(shí)現(xiàn)多線程同步的杀饵,和 synchronized 干的事一樣底哥,用法頁(yè)差不多咙鞍,但是比 synchronized 要靈活

其中 reentrantLock 叫重入鎖,condition 是阻塞條件趾徽,我們直接啊看用法來(lái)了解這2個(gè)類

實(shí)現(xiàn)鎖的功能

public class MyService {

    private Lock lock = new ReentrantLock();

    public void testMethod() {
        lock.lock();
        for (int i = 0; i < 5; i++) {
            System.out.println("ThreadName=" + Thread.currentThread().getName()
                    + (" " + (i + 1)));
        }
        lock.unlock();
    }
}

synchronized 因?yàn)楸旧硎顷P(guān)鍵字续滋,只能實(shí)現(xiàn)標(biāo)記,本身不含鎖孵奶,需要我們指定對(duì)象鎖疲酌。而新的 API ReentrantLock 本身就是把鎖,不用再依托別人了。

ReentrantLock 在使用上類似于 synchronized 的同步代碼塊朗恳,我們直接在需要的位置湿颅, new 一個(gè) ReentrantLock 鎖出來(lái),然后 lock() 就能鎖定同步粥诫,unlock() 就能解鎖同步油航,注意unlock() 方法推薦寫在 finnaly 里面

Condition 來(lái)阻塞線程并釋放鎖

public class MyService {

    private Lock lock = new ReentrantLock();
    private Condition condition=lock.newCondition();
    public void testMethod() {
        
        try {
            lock.lock();
            System.out.println("開始wait");
            condition.await();
            for (int i = 0; i < 5; i++) {
                System.out.println("ThreadName=" + Thread.currentThread().getName()
                        + (" " + (i + 1)));
            }
        } catch (InterruptedException e) {
            // TODO 自動(dòng)生成的 catch 塊
            e.printStackTrace();
        }
        finally
        {
            lock.unlock();
        }
    }
}

Condition 的 await() 會(huì)阻塞當(dāng)前線程,并釋放鎖怀浆、signal() 方法喚醒 wait 阻塞的線程谊囚。

Condition.awiat() = Object.wait()
Condition.signal() = Object.notify()
Condition.signalAll() = Object.notifyAll()

reentrantLock 和 condition 都是成對(duì)出現(xiàn),一個(gè) reentrantLock 里面可以有多個(gè) condition 阻塞條件對(duì)象揉稚,需要知道的是 conditionA await 阻塞的線程對(duì)象會(huì)放在這個(gè) conditionA 的阻塞隊(duì)列里秒啦,也只能由 conditionA signalAll 喚醒。換一個(gè) condition 對(duì)象 conditionB 是不管用的

線程池的阻塞隊(duì)列里面大量使用了 reentrantLock 搀玖,condition 余境,一般我們直接用 reentrantLock 、 condition 的時(shí)候比較少灌诅,雖然 reentrantLock 的性能比 synchronized 要好芳来,但是在使用上沒(méi)有 synchronized 方便啊,synchronized 關(guān)鍵字乙方就完了猜拾,我們就不用管了即舌。不過(guò) reentrantLock 、 condition 的 API 我們要熟挎袜,很多時(shí)候看別人的代碼時(shí)會(huì)用到顽聂。

ReentrantLock類的方法


  • getHoldCount()
    查詢當(dāng)前線程保持此鎖的次數(shù),也就是執(zhí)行此線程執(zhí)行l(wèi)ock方法的次數(shù)

  • getQueueLength()
    返回正等待獲取此鎖的線程估計(jì)數(shù)盯仪,比如啟動(dòng)10個(gè)線程紊搪,1個(gè)線程獲得鎖,此時(shí)返回的是9

  • getWaitQueueLength(Condition condition)
    返回等待與此鎖相關(guān)的給定條件的線程估計(jì)數(shù)全景。比如10個(gè)線程耀石,用同一個(gè)condition對(duì)象,并且此時(shí)這10個(gè)線程都執(zhí)行了condition對(duì)象的await方法爸黄,那么此時(shí)執(zhí)行此方法返回10

  • hasWaiters(Condition condition)
    查詢是否有線程等待與此鎖有關(guān)的給定條件(condition)滞伟,對(duì)于指定contidion對(duì)象,有多少線程執(zhí)行了condition.await方法

  • hasQueuedThread(Thread thread)
    查詢給定線程是否等待獲取此鎖

  • hasQueuedThreads()
    是否有線程等待此鎖

  • isFair()該鎖是否公平鎖

  • isHeldByCurrentThread() 當(dāng)前線程是否保持鎖鎖定炕贵,線程的執(zhí)行l(wèi)ock方法的前后分別是false和true

  • isLock()
    此鎖是否有任意線程占用

  • lockInterruptibly()
    如果當(dāng)前線程未被中斷梆奈,獲取鎖

  • tryLock()
    嘗試獲得鎖,僅在調(diào)用時(shí)鎖未被線程占用称开,獲得鎖

  • tryLock(long timeout TimeUnit unit)
    如果鎖在給定等待時(shí)間內(nèi)沒(méi)有被另一個(gè)線程保持鉴裹,則獲取該鎖

Lock類分公平鎖和不公平鎖,公平鎖是按照加鎖順序來(lái)的,非公平鎖是不按順序的径荔,也就是說(shuō)先執(zhí)行l(wèi)ock方法的鎖不一定先獲得鎖

reentrantLock 的確要靈活的多,我們不用使用別的鎖了脆霎,在想要的位置直接 new 一把鎖总处,阻塞的條件可以有多個(gè),可以實(shí)現(xiàn)復(fù)雜的操作睛蛛,這是阻塞隊(duì)列的核心鹦马。另外 reentrantLock 可以使用 tryLock 嘗試獲得鎖,可以避免一直卡在這里競(jìng)爭(zhēng)鎖忆肾。reentrantLock 對(duì)于高玩來(lái)說(shuō)是個(gè)可以極大發(fā)揮的東西荸频,但是對(duì)于 coder 們來(lái)說(shuō),還是在項(xiàng)目縱謹(jǐn)慎使用客冈。

下面是一個(gè)對(duì) ReentrantLock 中肯的評(píng)價(jià)

既然如此旭从,我們什么時(shí)候才應(yīng)該使用 ReentrantLock 呢?答案非常簡(jiǎn)單 —— 在確實(shí)需要一些 synchronized 所沒(méi)有的特性的時(shí)候场仲,比如時(shí)間鎖等候和悦、可中斷鎖等候、無(wú)塊結(jié)構(gòu)鎖渠缕、多個(gè)條件變量或者鎖投票鸽素。 ReentrantLock 還具有可伸縮性的好處,應(yīng)當(dāng)在高度爭(zhēng)用的情況下使用它亦鳞,但是請(qǐng)記住馍忽,大多數(shù) synchronized 塊幾乎從來(lái)沒(méi)有出現(xiàn)過(guò)爭(zhēng)用,所以可以把高度爭(zhēng)用放在一邊燕差。我建議用 synchronized 開發(fā)遭笋,直到確實(shí)證明 synchronized 不合適,而不要僅僅是假設(shè)如果使用 ReentrantLock “性能會(huì)更好”谁不。請(qǐng)記住坐梯,這些是供高級(jí)用戶使用的高級(jí)工具。(而且刹帕,真正的高級(jí)用戶喜歡選擇能夠找到的最簡(jiǎn)單工具吵血,直到他們認(rèn)為簡(jiǎn)單的工具不適用為止。)偷溺。一如既往蹋辅,首先要把事情做好,然后再考慮是不是有必要做得更快挫掏。

參考資料:


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市褒傅,隨后出現(xiàn)的幾起案子弃锐,更是在濱河造成了極大的恐慌,老刑警劉巖殿托,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件霹菊,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡支竹,警方通過(guò)查閱死者的電腦和手機(jī)旋廷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)礼搁,“玉大人饶碘,你說(shuō)我怎么就攤上這事÷猓” “怎么了扎运?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)募书。 經(jīng)常有香客問(wèn)我绪囱,道長(zhǎng),這世上最難降的妖魔是什么莹捡? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任鬼吵,我火速辦了婚禮,結(jié)果婚禮上篮赢,老公的妹妹穿的比我還像新娘齿椅。我一直安慰自己,他們只是感情好启泣,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布涣脚。 她就那樣靜靜地躺著,像睡著了一般寥茫。 火紅的嫁衣襯著肌膚如雪遣蚀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天纱耻,我揣著相機(jī)與錄音芭梯,去河邊找鬼。 笑死弄喘,一個(gè)胖子當(dāng)著我的面吹牛玖喘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蘑志,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼累奈,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼贬派!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起澎媒,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤搞乏,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后戒努,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體查描,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年柏卤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匀油。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缘缚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出敌蚜,到底是詐尸還是另有隱情桥滨,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布弛车,位于F島的核電站齐媒,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏纷跛。R本人自食惡果不足惜喻括,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望贫奠。 院中可真熱鬧唬血,春花似錦、人聲如沸唤崭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)谢肾。三九已至腕侄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間芦疏,已是汗流浹背冕杠。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留眯分,地道東北人拌汇。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像弊决,于是被迫代替她去往敵國(guó)和親噪舀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子魁淳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 作者: 一字馬胡 轉(zhuǎn)載標(biāo)志 【2017-11-03】 更新日志 前言 在java中,鎖是實(shí)現(xiàn)并發(fā)的關(guān)鍵組件与倡,多個(gè)...
    一字馬胡閱讀 44,143評(píng)論 1 32
  • ?既然java內(nèi)置了synchronized界逛,為什么還要出現(xiàn)lock呢??由于synchronized的并發(fā)是阻塞...
    扈扈哈嘿閱讀 888評(píng)論 0 1
  • Java-Review-Note——4.多線程 標(biāo)簽: JavaStudy PS:本來(lái)是分開三篇的纺座,后來(lái)想想還是整...
    coder_pig閱讀 1,629評(píng)論 2 17
  • PCA 算法主要是把高維度的數(shù)據(jù)降為低維度數(shù)據(jù)息拜。典型地應(yīng)用包括數(shù)據(jù)壓縮和數(shù)據(jù)可視化。本文介紹 PCA 算法及其典型...
    kamidox閱讀 4,941評(píng)論 6 12
  • 1 在佛山學(xué)習(xí)了6天净响,今天決定回去少欺,上午10:30看票,最合適的13:50廣州到長(zhǎng)沙馋贤,歷經(jīng)7小時(shí)22分(還是要省學(xué)...
    橘子778閱讀 214評(píng)論 0 2