(六)Lock鎖的使用&并發(fā)問題


1、簡介:“手動”或“鏈鎖定”,synchronized不容易實現(xiàn),Lock容易,如:您獲取節(jié)點A的鎖定,然后獲取節(jié)點B,然后釋放A并獲取C,然后釋放B并獲得D等

2、Lock接口實現(xiàn)類:?ReentrantLock , ReentrantReadWriteLock.ReadLock , ReentrantReadWriteLock.WriteLock

注意:?不要在try中獲取鎖,拋異常出導致無法釋放

3、 Lock接口的特性和常見方法

提供的synchronized不具備的主要特性:

1)嘗試非阻塞獲鎖 :嘗試獲取鎖,某一刻成功獲取并持有鎖

2)能被中斷獲鎖:取到鎖線程能響應中斷,中斷異常拋出,同時鎖釋放

3)超時獲取鎖?:超時沒獲取,則返回

4、Lock接口基本的方法:

void lock():獲得鎖。如鎖不可用休眠直到獲取鎖。

void lockInterruptibly()可用立即返回同上,只是獲取中可以中斷當前線程

Condition newCondition():獲取等待通知組件,該組件和當前鎖綁定,當前線程只獲得鎖,才能調用該組件wait(),調用后釋放鎖

boolean tryLock()調用時才可獲鎖可用返回true;不可用false 。

boolean tryLock(long time, TimeUnit unit)超時則結束,返回false.????可被中斷

void unlock():釋放鎖。

二 Lock接口的實現(xiàn)類:ReentrantLock

ReentrantLock和synchronized關鍵字一樣可以用來實現(xiàn)線程之間同步互斥,但更強大更靈活

線程鎖釋放,其他線程才執(zhí)行(執(zhí)行順序不確定的)

2.2 Condition接口簡介

實現(xiàn)等待/通知機制,newCondition() 方法

靈活性如:多路通知,一個Lock對象中可創(chuàng)建多個Condition實例即對象監(jiān)視器),線程對象注冊指定Condition中,選擇性線程通知

synchronized當于整個Lock對象中只有一個Condition實例,所有線程都注冊一個身上。

1)signalAll():喚醒注冊Condition中所有等待線程,notifyAll()造成很大的效率問題

2)void await():相當Object類wait

3)boolean await(long time, TimeUnit unit):相當Object類wait(long timeout)

2.3? 用單個Condition實現(xiàn)等待/通知機制:UseSingleConditionWaitNotify.java

2.4 公平鎖與非公平鎖

公平鎖?:FIFO先進先出順序

非公平鎖隨機獲取鎖的、ReentranLock默認非公平鎖

final Service service = new Service(false); //true為公平鎖,false為非公平鎖

三 ReadWriteLock接口的實現(xiàn)類:ReentrantReadWriteLock?

ReentrantLock(排他鎖)保證線程安全性,但效率低。ReadWriteLock接口的實現(xiàn)類-ReentrantReadWriteLock讀寫鎖解決

維護兩個鎖,共享鎖寫操作排他鎖。分離讀寫并發(fā)性提升有寫就互斥

原文:https://blog.csdn.net/qq_34337272/article/details/79714196

并發(fā)問題

并發(fā)問題:內存泄漏、上下文切換、死鎖還有受限于硬件和軟件的資源閑置

多線程:CPU通過給每個線程分配CPU時間片實現(xiàn)偽同時運行,CPU時間片很短很短,給人同時運行的感覺。

一、上下文切換

消耗大量的 CPU 時間,Linux切換時間消耗非常少。

1.讓步式:執(zhí)行線程主動釋放CPU,與鎖競爭程度正比,如何避免:減少鎖競爭和用CAS算法(無鎖)

2.搶占式:時間片用盡而被迫放棄CPU優(yōu)先級高線程所搶占,線程數(shù)大于CPU可用核心數(shù)引起,如何避免:減少線程數(shù)協(xié)程

CAS算法(Compare and swap)?無鎖實現(xiàn),多線程間的變量同步,也叫非阻塞同步

ps:獨占鎖是悲觀鎖,如synchronized,最壞導致所有需要鎖的線程掛起

二、避免死鎖

死鎖:兩個線程互相等待

1.避免一個線程同時獲得多個鎖

2.避免一個線程在鎖內同時占用多個資源,盡量保證每個鎖只占用一個資源

3.嘗試用定時鎖lock.tryLock(timeout)替代內部鎖

4.加鎖和解鎖必須在一個數(shù)據(jù)庫連接里,否則鎖失敗

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 摘要: 我們已經(jīng)知道,synchronized 是Java的關鍵字,是Java的內置特性,在JVM層面實現(xiàn)了對臨界...
    kingZXY2009閱讀 1,845評論 0 20
  • 一、進程和線程 進程 進程就是一個執(zhí)行中的程序實例,每個進程都有自己獨立的一塊內存空間,一個進程中可以有多個線程。...
    阿敏其人閱讀 2,622評論 0 13
  • 去鳳凰的事兒已經(jīng)過了一個多月了,這是我們第一次真正意義上的旅行,盡管我們還有還兩個同伴。去鳳凰是去年冬天就...
    巴拉巴拉biu閱讀 307評論 0 1
  • 群夏的燥熱總是給人們借口肆意 貪戀雨天的蕭瑟 這是給予時間感受暗夜的秘密 就這樣在路上走 一...
    衫妲閱讀 109評論 10 3
  • 對的,這就是一個永遠不會賠的互聯(lián)網(wǎng)賺錢方式。 今年雙十一,天貓1680的成交額告訴我們今年的淘寶店主們又賺了不少,...
    余生輝啊閱讀 230評論 0 0