Java Synchronized

一肩袍、為什么需要鎖

存在共享數(shù)據(jù)中贝。
當(dāng)出現(xiàn)ConcurrentModificationException的時候等太,存在多個線程對一個集合同時進行遍歷或者修改。
單線程就不需要考慮這種情況规哲。

二播赁、解決方案

當(dāng)前類中涉及集合修改和遍歷操作加上synchronized關(guān)鍵字庐氮,或者是這兩個邏輯放在一個線程中完成膘茎。

1、可重入&&互斥

synchronized是可重入鎖脚草;ReentrantLock也是赫悄。
即同一個線程可以輸出Hello World不會死鎖。

    // 可重入
    public void syncsTask() {
        synchronized (this) {
            System.out.println("Hello");
            synchronized (this){
                System.out.println("World");
            }
        }
    }

synchronized是互斥鎖,滿足互斥性(操作的原子性)埂淮,可見性嚼贡。
synchronized鎖的不是代碼,是對象同诫。
同步代碼塊synchronized(this)和同步方法鎖的是同一個對象粤策。
類鎖和對象鎖是互不干擾的。只有使用同一把鎖線程之間才會干擾误窖。
Java對象頭中都存在一個Monitor對象叮盘,這也是Java中任意對象可以作為鎖的原因。

2霹俺、為什么很多人對它嗤之以鼻

早前版本是重量級鎖柔吼,依賴于系統(tǒng)的Mutex Lock(互斥),線程之間切換從用戶態(tài)轉(zhuǎn)換至核心態(tài)丙唧,開銷大愈魏。
jdk6之后性能已經(jīng)提升。

3想际、自旋鎖與自適應(yīng)自旋鎖

jdk6默認(rèn)開啟培漏,不掛起線程,但如果鎖占用時間過長胡本,就不再推薦使用了牌柄。
讓線程處于忙循環(huán)等待鎖釋放,不出讓CPU侧甫,減少線程的切換珊佣。

4、鎖消除

JIT編譯時披粟,對運行上下文進行掃描咒锻,去除不可能存在競爭的鎖。

5守屉、鎖粗化

JVM對鎖的范圍進行擴大惑艇,減少鎖同步的代價。

6胸梆、synchronized的四個演變階段

鎖膨脹的方向:無鎖敦捧、偏向鎖须板、輕量級鎖碰镜、重量級鎖
偏向鎖:CAS,指一段同步代碼一直被一個線程所訪問习瑰,那么該線程會自動獲取鎖绪颖,降低獲取鎖的代價
輕量級鎖:偏向鎖升級而來,適用于線程交替執(zhí)行同步塊,自旋
重量級鎖:同步塊或者方法執(zhí)行時間較長柠横,追求吞吐量


對象頭不同階段的演變

三窃款、synchronized和static synchronized區(qū)別

一個鎖的是類對象,一個鎖的是實例對象牍氛。
若類對象被lock晨继,則類對象的所有同步方法(static synchronized 修飾)全被lock;
若實例對象被lock搬俊,則該實例對象的所有同步方法(synchronized 修飾)全被lock紊扬。
每個synchronized方法都必須獲得調(diào)用該方法的類實例的”鎖“方能執(zhí)行,否則所屬線程阻塞唉擂。

方法一旦執(zhí)行餐屎,就會獨占該鎖,一直到從該方法返回時才將鎖釋放玩祟,此后被阻塞的線程方能獲得該鎖腹缩,從而重新進入可執(zhí)行狀態(tài)。這種機制確保了同一時刻對于每一個類的實例空扎,其所有聲明為synchronized的成員函數(shù)中之多只有一個處于可執(zhí)行狀態(tài)藏鹊,從而有效避免了類成員變量的訪問沖突。

四转锈、synchronized方法與synchronized代碼塊

    private synchronized void syncFunc() {
        // do something
    }

    private void syncBlockFunc() {
        synchronized (this) {
            // do something
        }
    }

synchronized methods() {}與synchronized(this){}之間沒有什么區(qū)別伙判,只是synchronized methods() {} 便于閱讀理解,而synchronized(this){}可以更精確的控制沖突限制訪問區(qū)域黑忱,有時候表現(xiàn)更高效率宴抚。

五、synchronized和ReentrantLock區(qū)別

所屬不同關(guān)鍵字甫煞,類菇曲。
底層實現(xiàn)不同MarkWord,Unsafe類抚吠。
ReentrantLock可以選擇公平(fair)鎖(排隊打飯)和非公平鎖常潮,構(gòu)造函數(shù)傳入true;
synchronized是非公平的(堵車時的加塞)楷力。

// 一般通常會使用try catch finally方式
public class ReentrantLockDemo implements Runnable {
    private static ReentrantLock lock = new ReentrantLock(false);

    @Override
    public void run() {
        while (true) {
            try {
                lock.lock();
                System.out.println(Thread.currentThread().getName() + " get lock");
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
                break;
            } finally {
                lock.unlock();
            }
        }
    }

將synchronized轉(zhuǎn)換為直觀可控的對象行為喊式。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市萧朝,隨后出現(xiàn)的幾起案子岔留,更是在濱河造成了極大的恐慌,老刑警劉巖检柬,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件献联,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機里逆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門进胯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人原押,你說我怎么就攤上這事胁镐。” “怎么了诸衔?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵希停,是天一觀的道長。 經(jīng)常有香客問我署隘,道長宠能,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任磁餐,我火速辦了婚禮违崇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘诊霹。我一直安慰自己羞延,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布脾还。 她就那樣靜靜地躺著伴箩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鄙漏。 梳的紋絲不亂的頭發(fā)上嗤谚,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天,我揣著相機與錄音怔蚌,去河邊找鬼巩步。 笑死,一個胖子當(dāng)著我的面吹牛桦踊,可吹牛的內(nèi)容都是我干的椅野。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼籍胯,長吁一口氣:“原來是場噩夢啊……” “哼竟闪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起杖狼,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤炼蛤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后本刽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鲸湃,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年子寓,在試婚紗的時候發(fā)現(xiàn)自己被綠了暗挑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡斜友,死狀恐怖炸裆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鲜屏,我是刑警寧澤烹看,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站洛史,受9級特大地震影響惯殊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜也殖,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一土思、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧忆嗜,春花似錦己儒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至绩卤,卻和暖如春途样,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背濒憋。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工娘纷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人跋炕。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓赖晶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親辐烂。 傳聞我的和親對象是個殘疾皇子遏插,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

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

  • 由于同一進程的多個線程共享同一片存儲空間,在帶來方便的同時纠修,也帶來了訪問沖突這個嚴(yán)重的問題胳嘲。Java語言提供了專門...
    DanieX閱讀 16,365評論 7 16
  • 由于同一進程的多個線程共享同一片存儲空間,在帶來方便的同時扣草,也帶來了訪問沖突這個嚴(yán)重的問題了牛。Java語言提供了專門...
    Mracale閱讀 266評論 0 0
  • 一:概述 java發(fā)生線程安全的有原因有兩個因素:第一颜屠,存在共享資源(也稱臨界資源,不知道為什么取這破名字)鹰祸;第二...
    涂豪_OP閱讀 754評論 0 1
  • Java 15 廢棄偏向鎖 JDK 15已經(jīng)在2020年9月15日發(fā)布,詳情見 JDK 15 官方計劃[https...
    被稱為L的男人閱讀 269評論 0 1
  • synchronized的用法 在平常的編碼過程中蛙婴,使用synchronized一般有三種方法:1粗井、同步實例方法2...
    符夕閱讀 193評論 0 0