最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java synchronized關(guān)鍵字從入門(mén)到原理解析

 更新時(shí)間:2026年02月24日 09:44:03   作者:百錦再@新空間創(chuàng)想科技  
這篇文章介紹Java synchronized關(guān)鍵字從入門(mén)到原理,本課程適合具備Java基礎(chǔ)語(yǔ)法知識(shí),初步了解多線程概念但尚未系統(tǒng)學(xué)習(xí)并發(fā)編程的開(kāi)發(fā)者,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

適用對(duì)象

本課程適合具備Java基礎(chǔ)語(yǔ)法知識(shí),初步了解多線程概念但尚未系統(tǒng)學(xué)習(xí)并發(fā)編程的開(kāi)發(fā)者。無(wú)論你是準(zhǔn)備面試的求職者,還是希望提升并發(fā)編程能力的工程師,這門(mén)課程都將為你打下堅(jiān)實(shí)基礎(chǔ)。

學(xué)習(xí)目標(biāo)

通過(guò)兩個(gè)課時(shí)的系統(tǒng)學(xué)習(xí),你將能夠:

  • 掌握 synchronized的三種使用方式及其區(qū)別
  • 理解 synchronized解決線程安全問(wèn)題的核心原理
  • 剖析 synchronized底層的Monitor機(jī)制和鎖升級(jí)過(guò)程
  • 區(qū)分 synchronized與volatile、ReentrantLock的適用場(chǎng)景
  • 應(yīng)對(duì) 面試中關(guān)于synchronized的高頻問(wèn)題

課程安排

  • 第一課時(shí)(約40分鐘):基礎(chǔ)概念、使用方式、特性詳解
  • 第二課時(shí)(約50分鐘):底層原理、鎖升級(jí)機(jī)制、對(duì)比與實(shí)戰(zhàn)

第一課時(shí):synchronized基礎(chǔ)與使用

1.1 從一個(gè)線程安全問(wèn)題開(kāi)始

讓我們先看一個(gè)經(jīng)典問(wèn)題:兩個(gè)線程同時(shí)對(duì)共享變量執(zhí)行自增操作。

public class Counter {
    private int count = 0;
    public void increment() {
        count++; // 不是原子操作!
    }
    public int getCount() {
        return count;
    }
}
// 測(cè)試代碼
public class Test {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 10000; i++) counter.increment();
        });
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 10000; i++) counter.increment();
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("最終結(jié)果: " + counter.getCount()); // 期望20000,實(shí)際小于20000
    }
}

運(yùn)行結(jié)果:多次執(zhí)行,結(jié)果總是小于20000,有時(shí)甚至相差甚遠(yuǎn)。

問(wèn)題根源count++看似一行代碼,但在JVM中分解為三條指令:

  1. 從主內(nèi)存讀取count到工作內(nèi)存(讀)
  2. 對(duì)count進(jìn)行加1操作(改)
  3. 將結(jié)果寫(xiě)回主內(nèi)存(寫(xiě))

當(dāng)兩個(gè)線程同時(shí)執(zhí)行這三步時(shí),可能發(fā)生交替執(zhí)行,導(dǎo)致最后寫(xiě)入的值覆蓋了之前的計(jì)算結(jié)果——這就是典型的競(jìng)態(tài)條件。

1.2 synchronized是什么?

synchronized是Java提供的一個(gè)關(guān)鍵字,譯為“同步”。它可以保證在同一時(shí)刻,最多只有一個(gè)線程執(zhí)行被它修飾的代碼段,從而解決并發(fā)環(huán)境下的線程安全問(wèn)題。

從專業(yè)角度說(shuō),synchronized實(shí)現(xiàn)了互斥訪問(wèn),它保證了三個(gè)關(guān)鍵特性:

特性說(shuō)明
原子性被保護(hù)的代碼塊要么全部執(zhí)行,要么完全不執(zhí)行,不會(huì)被打斷
可見(jiàn)性一個(gè)線程修改共享變量后,其他線程能立即看到最新值
有序性禁止編譯器和處理器對(duì)同步塊內(nèi)的代碼進(jìn)行指令重排序

1.3 初識(shí)synchronized的三種用法

synchronized的使用非常靈活,可以根據(jù)需要選擇不同的加鎖對(duì)象。下面我們通過(guò)三個(gè)典型場(chǎng)景來(lái)理解它們的區(qū)別。

1.3.1 修飾實(shí)例方法

public class SyncMethodDemo {
    private int count = 0;
    // synchronized修飾實(shí)例方法,鎖是當(dāng)前對(duì)象this
    public synchronized void increment() {
        count++;
    }
}

特點(diǎn)

  • 鎖對(duì)象是調(diào)用該方法的實(shí)例對(duì)象(即this)
  • 同一個(gè)對(duì)象的多個(gè)synchronized實(shí)例方法,共用同一把鎖
  • 不同對(duì)象的方法互不干擾

示意圖

線程A ──> obj1.increment() ──> 獲取obj1鎖 ──> 執(zhí)行
線程B ──> obj1.increment() ──> 等待obj1鎖
線程C ──> obj2.increment() ──> 獲取obj2鎖 ──> 執(zhí)行(與A不沖突)

1.3.2 修飾靜態(tài)方法

public class SyncStaticDemo {
    private static int count = 0;
    // synchronized修飾靜態(tài)方法,鎖是當(dāng)前類(lèi)的Class對(duì)象
    public static synchronized void increment() {
        count++;
    }
}

特點(diǎn)

  • 鎖對(duì)象是當(dāng)前類(lèi)的Class對(duì)象(如SyncStaticDemo.class)
  • 所有實(shí)例對(duì)象共享同一把類(lèi)鎖
  • 靜態(tài)方法鎖與實(shí)例方法鎖互不干擾

思考題:如果一個(gè)類(lèi)既有synchronized靜態(tài)方法,又有synchronized實(shí)例方法,兩個(gè)線程分別調(diào)用它們,會(huì)互斥嗎?

  • 答案:不會(huì)。因?yàn)橐粋€(gè)是類(lèi)鎖,一個(gè)是對(duì)象鎖,兩把不同的鎖。

1.3.3 修飾代碼塊

public class SyncBlockDemo {
    private Object lock = new Object();
    private int count = 0;
    public void increment() {
        // 同步代碼塊,鎖是指定的lock對(duì)象
        synchronized (lock) {
            count++;
        }
    }
    public void decrement() {
        // 也可以鎖this
        synchronized (this) {
            count--;
        }
    }
}

特點(diǎn)

  • 鎖對(duì)象可以任意指定,靈活性最高
  • 可以精確控制同步范圍,提高并發(fā)性能
  • 常用鎖對(duì)象:this、自定義鎖對(duì)象、類(lèi).class

1.4 深入理解鎖的范圍

1.4.1 三種鎖的對(duì)比表格

使用形式鎖對(duì)象作用范圍典型應(yīng)用場(chǎng)景
修飾實(shí)例方法當(dāng)前實(shí)例對(duì)象單個(gè)實(shí)例內(nèi)保護(hù)實(shí)例變量
修飾靜態(tài)方法當(dāng)前類(lèi)的Class對(duì)象所有實(shí)例間保護(hù)靜態(tài)變量
修飾代碼塊指定的任意對(duì)象代碼塊內(nèi)細(xì)粒度控制

1.4.2 常見(jiàn)面試題解析

問(wèn)題1:synchronized修飾代碼塊可以給類(lèi)加鎖嗎?
當(dāng)然可以!只要在括號(hào)內(nèi)傳入類(lèi)名.class即可。例如:

synchronized (SyncBlockDemo.class) {
    // 這是類(lèi)鎖
}

問(wèn)題2:構(gòu)造方法可以用synchronized修飾嗎?
不可以!Java語(yǔ)法規(guī)定構(gòu)造方法不能是同步的。實(shí)際上,構(gòu)造方法本身就是線程安全的,因?yàn)镴VM會(huì)保證在對(duì)象初始化完成前,其他線程無(wú)法訪問(wèn)該對(duì)象。

問(wèn)題3:靜態(tài)同步方法和非靜態(tài)同步方法同時(shí)調(diào)用會(huì)互斥嗎?
不會(huì)互斥。假設(shè)線程A調(diào)用實(shí)例對(duì)象的非靜態(tài)同步方法,線程B同時(shí)調(diào)用該對(duì)象所屬類(lèi)的靜態(tài)同步方法,它們持有的是兩把不同的鎖(對(duì)象鎖 vs 類(lèi)鎖),因此可以并行執(zhí)行。

1.5 synchronized的核心特性

1.5.1 可重入性

概念:同一個(gè)線程在持有鎖的情況下,可以再次獲取同一把鎖,而不會(huì)被阻塞。

public class ReentrantDemo {
    public synchronized void methodA() {
        System.out.println("進(jìn)入methodA");
        methodB(); // 直接調(diào)用,不會(huì)死鎖
    }
    public synchronized void methodB() {
        System.out.println("進(jìn)入methodB");
    }
}

為什么需要可重入?
如果沒(méi)有可重入性,線程在調(diào)用methodA獲取鎖后,調(diào)用methodB時(shí)發(fā)現(xiàn)自己還要申請(qǐng)同一把鎖,就會(huì)形成死鎖。這顯然不合理。

實(shí)現(xiàn)原理:每個(gè)鎖關(guān)聯(lián)一個(gè)持有線程和一個(gè)計(jì)數(shù)器。線程第一次獲取鎖時(shí),計(jì)數(shù)器置為1;同一線程再次獲取時(shí),計(jì)數(shù)器遞增;釋放一次,計(jì)數(shù)器遞減。直到計(jì)數(shù)器歸零,鎖才真正釋放。

1.5.2 可見(jiàn)性保證

synchronized不僅能保證原子性,還能保證內(nèi)存可見(jiàn)性。JMM(Java內(nèi)存模型)規(guī)定:

  • 線程釋放鎖時(shí),會(huì)將工作內(nèi)存中的共享變量刷新到主內(nèi)存
  • 線程獲取鎖時(shí),會(huì)清空工作內(nèi)存,從主內(nèi)存重新讀取共享變量

這就確保了:一個(gè)線程修改的共享變量,在釋放鎖后,其他線程能立即看到最新值。

1.6 第一課時(shí)小結(jié)

  • synchronized是Java內(nèi)置的同步關(guān)鍵字,解決原子性、可見(jiàn)性、有序性問(wèn)題
  • 三種使用方式:實(shí)例方法(鎖this)、靜態(tài)方法(鎖Class對(duì)象)、代碼塊(鎖任意對(duì)象)
  • 核心特性:可重入性、可見(jiàn)性、互斥性
  • 不同鎖對(duì)象決定了不同的同步范圍

第二課時(shí):synchronized原理與優(yōu)化

2.1 從字節(jié)碼看synchronized的本質(zhì)

2.1.1 同步代碼塊的字節(jié)碼

先看一段簡(jiǎn)單的同步代碼塊:

public class SyncCodeBlock {
    public void doSomething() {
        synchronized (this) {
            System.out.println("hello");
        }
    }
}

使用javap -c -v反編譯后,關(guān)鍵字節(jié)碼如下:

 3: monitorenter      // 進(jìn)入同步塊,獲取監(jiān)視器鎖
 4: getstatic         // 調(diào)用System.out
 7: ldc               // 加載字符串
 9: invokevirtual     // 調(diào)用println
12: aload_1
13: monitorexit       // 退出同步塊,釋放監(jiān)視器鎖
14: goto 22           // 正常結(jié)束跳轉(zhuǎn)
17: astore_2          // 異常處理開(kāi)始
18: aload_1
19: monitorexit       // 異常時(shí)也釋放鎖
20: aload_2
21: athrow            // 拋出異常
22: return

關(guān)鍵發(fā)現(xiàn)

  • 同步代碼塊使用monitorentermonitorexit指令
  • 有兩個(gè)monitorexit:一個(gè)正常退出,一個(gè)異常退出,確保鎖一定被釋放
  • 這就是為什么synchronized即使拋出異常也不會(huì)死鎖

2.1.2 同步方法的字節(jié)碼

public synchronized void syncMethod() {
    System.out.println("hello");
}

反編譯結(jié)果:

public synchronized void syncMethod();
  descriptor: ()V
  flags: ACC_PUBLIC, ACC_SYNCHRONIZED  // 注意這個(gè)標(biāo)志
  Code:
   0: getstatic     #2
   3: ldc           #3
   5: invokevirtual #4
   8: return

同步方法沒(méi)有monitorenter/monitorexit指令,而是通過(guò)方法表flags中的ACC_SYNCHRONIZED標(biāo)識(shí)。JVM根據(jù)這個(gè)標(biāo)識(shí)判斷是否需要獲取鎖。

結(jié)論:兩種實(shí)現(xiàn)方式本質(zhì)上都是獲取對(duì)象的監(jiān)視器鎖(Monitor Lock),只是表現(xiàn)形式不同。

2.2 Monitor機(jī)制深度剖析

2.2.1 什么是Monitor?

Monitor(監(jiān)視器)是操作系統(tǒng)中用于實(shí)現(xiàn)線程同步的機(jī)制。Java中的每個(gè)對(duì)象都與一個(gè)Monitor關(guān)聯(lián),這個(gè)關(guān)聯(lián)關(guān)系存儲(chǔ)在對(duì)象頭的Mark Word中。

可以把Monitor理解為一個(gè)“接待室”,里面有三個(gè)關(guān)鍵區(qū)域:

                  ┌─────────────────────┐
                  │      Owner          │ ← 當(dāng)前持有鎖的線程
                  ├─────────────────────┤
                  │     EntryList       │ ← 等待獲取鎖的線程隊(duì)列
                  ├─────────────────────┤
                  │     WaitSet         │ ← 調(diào)用了wait()的線程隊(duì)列
                  └─────────────────────┘

2.2.2 Monitor的核心數(shù)據(jù)結(jié)構(gòu)

在HotSpot虛擬機(jī)中,Monitor由C++的ObjectMonitor類(lèi)實(shí)現(xiàn),關(guān)鍵字段如下:

字段作用
_owner指向當(dāng)前持有鎖的線程
_EntryList等待獲取鎖的線程隊(duì)列
_WaitSet調(diào)用了wait()的線程隊(duì)列
_recursions記錄鎖的重入次數(shù)
_count記錄線程獲取鎖的次數(shù)

2.2.3 鎖獲取和釋放的完整流程

以兩個(gè)線程T0和T1競(jìng)爭(zhēng)鎖為例:

步驟1:線程T0嘗試獲取鎖

  • 根據(jù)對(duì)象頭找到對(duì)應(yīng)的ObjectMonitor
  • 檢查_owner是否為null
  • 通過(guò)CAS操作將_owner設(shè)為T(mén)0,_count設(shè)為1
  • T0獲取鎖成功,進(jìn)入同步塊執(zhí)行

步驟2:線程T1嘗試獲取鎖

  • 此時(shí)_owner為T(mén)0,T1 CAS失敗
  • T1會(huì)先自旋幾次嘗試(適應(yīng)性自旋)
  • 如果T0很快釋放鎖,T1就成功獲取
  • 如果T0未釋放,T1進(jìn)入_EntryList阻塞等待

步驟3:T0釋放鎖

  • 執(zhí)行monitorexit_count減1
  • _count變?yōu)?,_owner設(shè)為null
  • 喚醒_EntryList中的線程(通常是隊(duì)首線程)
  • T1被喚醒,重新競(jìng)爭(zhēng)鎖

2.3 鎖升級(jí):從偏向鎖到重量級(jí)鎖

早期Java的synchronized性能較差,被稱為“重量級(jí)鎖”。JDK 1.6之后引入了一系列優(yōu)化,讓synchronized的性能大幅提升。這就是著名的鎖升級(jí)機(jī)制。

2.3.1 為什么需要鎖升級(jí)?

想象一下這些場(chǎng)景:

  • 場(chǎng)景A:只有一個(gè)線程訪問(wèn)同步代碼,根本不需要鎖競(jìng)爭(zhēng)
  • 場(chǎng)景B:兩個(gè)線程交替訪問(wèn),幾乎沒(méi)有同時(shí)競(jìng)爭(zhēng)
  • 場(chǎng)景C:多個(gè)線程激烈競(jìng)爭(zhēng),需要操作系統(tǒng)級(jí)別的鎖

如果用重量級(jí)鎖統(tǒng)一處理所有場(chǎng)景,場(chǎng)景A和B會(huì)造成不必要的性能開(kāi)銷(xiāo)。鎖升級(jí)就是讓synchronized能夠根據(jù)競(jìng)爭(zhēng)激烈程度,動(dòng)態(tài)調(diào)整鎖的“重量”。

2.3.2 鎖的四種狀態(tài)

從低到高,鎖有四種狀態(tài):

  1. 無(wú)鎖狀態(tài)
  2. 偏向鎖
  3. 輕量級(jí)鎖
  4. 重量級(jí)鎖

鎖可以升級(jí),但不能降級(jí)(除了一次GC清理)。

2.3.3 偏向鎖(Biased Locking)

適用場(chǎng)景:只有一個(gè)線程反復(fù)獲取同一把鎖。

原理

  • 第一次獲取鎖時(shí),通過(guò)CAS將線程ID記錄到對(duì)象頭
  • 之后該線程再來(lái)時(shí),只需檢查對(duì)象頭中是否是自己ID
  • 如果是,直接進(jìn)入,無(wú)需任何同步操作

示例代碼

public class BiasedLockDemo {
    private static List<Integer> list = new Vector<>(); // Vector的方法都是同步的
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            list.add(i); // 同一線程反復(fù)獲取鎖
        }
    }
}

優(yōu)點(diǎn):幾乎沒(méi)有加鎖開(kāi)銷(xiāo),性能極高。
缺點(diǎn):一旦有其他線程嘗試競(jìng)爭(zhēng),偏向鎖立即撤銷(xiāo)并升級(jí)。

注意:從JDK 15開(kāi)始,偏向鎖被標(biāo)記為廢棄,未來(lái)可能移除。因?yàn)樵趯?shí)際應(yīng)用中,它的性能提升有限,且維護(hù)成本高。

2.3.4 輕量級(jí)鎖(Lightweight Locking)

適用場(chǎng)景:兩個(gè)線程交替執(zhí)行同步塊,沒(méi)有真正的競(jìng)爭(zhēng)。

原理

  • 線程在自己的棧幀中創(chuàng)建Lock Record,存儲(chǔ)對(duì)象頭的拷貝
  • 通過(guò)CAS嘗試將對(duì)象頭指向Lock Record
  • 如果成功,獲取輕量級(jí)鎖
  • 如果失敗,說(shuō)明有競(jìng)爭(zhēng),升級(jí)為重量級(jí)鎖

輕量級(jí)鎖的解鎖

  • 通過(guò)CAS將對(duì)象頭恢復(fù)為原Mark Word
  • 如果恢復(fù)成功,解鎖完成
  • 如果失敗,說(shuō)明已經(jīng)升級(jí)為重量級(jí)鎖,走重量級(jí)鎖解鎖流程

2.3.5 重量級(jí)鎖(Heavyweight Locking)

適用場(chǎng)景:多個(gè)線程激烈競(jìng)爭(zhēng)。

原理

  • 線程進(jìn)入_EntryList隊(duì)列阻塞
  • 依賴操作系統(tǒng)Mutex Lock實(shí)現(xiàn)
  • 涉及用戶態(tài)和內(nèi)核態(tài)切換,開(kāi)銷(xiāo)較大

2.3.6 鎖升級(jí)流程總結(jié)

                   偏向鎖
                     │
                     │ 有其他線程嘗試獲取
                     ↓
                 輕量級(jí)鎖
                     │
                     │ 有真實(shí)競(jìng)爭(zhēng)
                     ↓
                 重量級(jí)鎖

2.4 synchronized與volatile的對(duì)比

特性synchronizedvolatile
原子性? 保證? 不保證
可見(jiàn)性? 保證? 保證
有序性? 保證? 保證(禁止重排序)
用法修飾方法或代碼塊修飾變量
性能較重(但有優(yōu)化)極輕
適用場(chǎng)景復(fù)合操作單一變量狀態(tài)標(biāo)志

volatile適用示例

public class VolatileDemo {
    private volatile boolean flag = true; // 只作為狀態(tài)標(biāo)志
    public void stop() {
        flag = false; // 簡(jiǎn)單寫(xiě)操作
    }
    public void run() {
        while (flag) {
            // 執(zhí)行任務(wù)
        }
    }
}

2.5 synchronized與ReentrantLock的對(duì)比

2.5.1 對(duì)比表格

對(duì)比維度synchronizedReentrantLock
實(shí)現(xiàn)方式JVM關(guān)鍵字Java API(基于AQS)
鎖釋放自動(dòng)釋放必須手動(dòng)unlock
公平性非公平可設(shè)置公平/非公平
可中斷不支持支持lockInterruptibly()
超時(shí)獲取不支持支持tryLock(timeout)
嘗試獲取不支持支持tryLock()
條件變量一個(gè)等待集多個(gè)Condition
鎖狀態(tài)查詢不支持支持查詢持有線程等

2.5.2 如何選擇?

優(yōu)先使用synchronized的情況:

  • 同步邏輯簡(jiǎn)單,不需要高級(jí)功能
  • 希望代碼簡(jiǎn)潔不易出錯(cuò)
  • JVM持續(xù)優(yōu)化,性能已很好

選擇ReentrantLock的情況:

  • 需要公平鎖
  • 需要嘗試獲取鎖或超時(shí)獲取
  • 需要可中斷的鎖獲取
  • 需要多個(gè)條件變量(如生產(chǎn)者-消費(fèi)者模式)
  • 高競(jìng)爭(zhēng)場(chǎng)景需要更精細(xì)控制

2.5.3 ReentrantLock使用示例

ReentrantLock lock = new ReentrantLock(true); // 公平鎖
Condition notFull = lock.newCondition();
Condition notEmpty = lock.newCondition();
// 標(biāo)準(zhǔn)使用模式
lock.lock();
try {
    // 臨界區(qū)代碼
    while (條件不滿足) {
        notEmpty.await(); // 等待
    }
    // 執(zhí)行操作
    notFull.signal();
} finally {
    lock.unlock(); // 必須釋放
}

2.6 實(shí)戰(zhàn):線程安全的單例模式

綜合運(yùn)用synchronized,實(shí)現(xiàn)幾種經(jīng)典的單例模式。

2.6.1 餓漢式(線程安全)

public class EagerSingleton {
    private static final EagerSingleton INSTANCE = new EagerSingleton();
    private EagerSingleton() {}
    public static EagerSingleton getInstance() {
        return INSTANCE;
    }
}

2.6.2 懶漢式(同步方法版)

public class LazySingleton {
    private static LazySingleton instance;
    private LazySingleton() {}
    public static synchronized LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

2.6.3 雙重檢查鎖(DCL)

public class DCLSingleton {
    // volatile保證可見(jiàn)性和禁止重排序
    private static volatile DCLSingleton instance;
    private DCLSingleton() {}
    public static DCLSingleton getInstance() {
        if (instance == null) {
            synchronized (DCLSingleton.class) {
                if (instance == null) {
                    instance = new DCLSingleton();
                }
            }
        }
        return instance;
    }
}

為什么需要volatile?
instance = new DCLSingleton()不是原子操作,可能發(fā)生指令重排序。如果不加volatile,其他線程可能拿到一個(gè)未初始化完成的對(duì)象。這是DCL的關(guān)鍵細(xì)節(jié)。

2.7 第二課時(shí)小結(jié)

  • synchronized底層基于Monitor實(shí)現(xiàn),字節(jié)碼層面使用monitorenter/monitorexit或ACC_SYNCHRONIZED
  • 鎖升級(jí)機(jī)制(偏向鎖→輕量級(jí)鎖→重量級(jí)鎖)大幅提升了性能
  • synchronized保證原子性、可見(jiàn)性、有序性,是全面的同步工具
  • 與volatile相比,synchronized更重量但功能更全
  • 與ReentrantLock相比,synchronized簡(jiǎn)單易用,ReentrantLock功能更豐富
  • 實(shí)際開(kāi)發(fā)中,根據(jù)場(chǎng)景選擇合適的同步機(jī)制

課程總結(jié)

通過(guò)兩個(gè)課時(shí)的學(xué)習(xí),我們?nèi)嬲莆樟藄ynchronized關(guān)鍵字:

  • 第一課時(shí):從線程安全問(wèn)題出發(fā),學(xué)習(xí)了synchronized的三種使用方式、鎖的范圍、可重入性等基礎(chǔ)概念
  • 第二課時(shí):深入底層,剖析了Monitor機(jī)制、鎖升級(jí)流程,并對(duì)比了volatile和ReentrantLock

synchronized作為Java最基礎(chǔ)的同步工具,雖然簡(jiǎn)單,但背后的原理并不簡(jiǎn)單。理解它的實(shí)現(xiàn)機(jī)制,不僅能幫助我們寫(xiě)出更正確的并發(fā)程序,還能在面試中脫穎而出。

課后思考題

  1. 如果一個(gè)線程在同步塊中拋出異常,鎖會(huì)自動(dòng)釋放嗎?為什么?
  2. 偏向鎖在JDK 15中被廢棄的原因是什么?談?wù)勀愕睦斫狻?/li>
  3. 如何用synchronized實(shí)現(xiàn)一個(gè)阻塞隊(duì)列?
  4. 為什么說(shuō)synchronized是“悲觀鎖”,而CAS是“樂(lè)觀鎖”?

到此這篇關(guān)于Java synchronized關(guān)鍵字詳解:從入門(mén)到原理(兩課時(shí))的文章就介紹到這了,更多相關(guān)Java synchronized關(guān)鍵字內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java線程池的簡(jiǎn)單使用方法實(shí)例教程

    Java線程池的簡(jiǎn)單使用方法實(shí)例教程

    線程的使用在java中占有極其重要的地位,在jdk1.4極其之前的jdk版本中,關(guān)于線程池的使用是極其簡(jiǎn)陋的,在jdk1.5之后這一情況有了很大的改,這篇文章主要給大家介紹了關(guān)于Java線程池的簡(jiǎn)單使用方法,需要的朋友可以參考下
    2021-10-10
  • Java多線程窗口售票問(wèn)題實(shí)例

    Java多線程窗口售票問(wèn)題實(shí)例

    這篇文章主要介紹了Java多線程窗口售票問(wèn)題實(shí)例,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • Spring?boot整合jsp和tiles模板示例

    Spring?boot整合jsp和tiles模板示例

    這篇文章主要介紹了Spring?boot整合jsp模板和tiles模板的示例演示過(guò)程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • Spring boot如何通過(guò)@Scheduled實(shí)現(xiàn)定時(shí)任務(wù)及多線程配置

    Spring boot如何通過(guò)@Scheduled實(shí)現(xiàn)定時(shí)任務(wù)及多線程配置

    這篇文章主要介紹了Spring boot如何通過(guò)@Scheduled實(shí)現(xiàn)定時(shí)任務(wù)及多線程配置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Java實(shí)現(xiàn)模擬機(jī)器人對(duì)話的示例代碼

    Java實(shí)現(xiàn)模擬機(jī)器人對(duì)話的示例代碼

    本文主要介紹了Java實(shí)現(xiàn)模擬機(jī)器人對(duì)話的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • 最新Spring Security的基于內(nèi)存用戶認(rèn)證方式

    最新Spring Security的基于內(nèi)存用戶認(rèn)證方式

    本文講解SpringSecurity內(nèi)存認(rèn)證配置,適用于開(kāi)發(fā)、測(cè)試等場(chǎng)景,通過(guò)代碼創(chuàng)建用戶及權(quán)限管理,支持密碼加密,雖簡(jiǎn)單但不持久化,生產(chǎn)環(huán)境推薦使用數(shù)據(jù)庫(kù)或JWT等認(rèn)證方式,感興趣的朋友一起看看吧
    2025-07-07
  • Java實(shí)現(xiàn)在線五子棋對(duì)戰(zhàn)游戲(人機(jī)對(duì)戰(zhàn))

    Java實(shí)現(xiàn)在線五子棋對(duì)戰(zhàn)游戲(人機(jī)對(duì)戰(zhàn))

    這篇文章主要為大家詳細(xì)介紹了如何利用Java語(yǔ)言實(shí)現(xiàn)在線五子棋對(duì)戰(zhàn)游戲(人機(jī)對(duì)戰(zhàn)),文中的實(shí)現(xiàn)步驟講解詳細(xì),感興趣的可以嘗試一下
    2022-09-09
  • JDBC利用C3P0數(shù)據(jù)庫(kù)連接池連接數(shù)據(jù)庫(kù)

    JDBC利用C3P0數(shù)據(jù)庫(kù)連接池連接數(shù)據(jù)庫(kù)

    這篇文章主要為大家詳細(xì)介紹了JDBC利用C3P0數(shù)據(jù)庫(kù)連接池連接數(shù)據(jù)庫(kù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • Java Socket+多線程實(shí)現(xiàn)多人聊天室功能

    Java Socket+多線程實(shí)現(xiàn)多人聊天室功能

    這篇文章主要為大家詳細(xì)介紹了Java Socket+多線程實(shí)現(xiàn)多人聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 解讀GC日志中的各項(xiàng)指標(biāo)用法

    解讀GC日志中的各項(xiàng)指標(biāo)用法

    這篇文章主要介紹了GC日志中的各項(xiàng)指標(biāo)用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-07-07

最新評(píng)論

福鼎市| 马鞍山市| 青冈县| 彩票| 德惠市| 青冈县| 东丰县| 沧州市| 青铜峡市| 随州市| 巢湖市| 二连浩特市| 高唐县| 鄂托克旗| 深州市| 岗巴县| 德令哈市| 漠河县| 富民县| 柘荣县| 古浪县| 郎溪县| 施甸县| 卓资县| 东兴市| 光山县| 娱乐| 三原县| 广德县| 普格县| 南昌县| 仙游县| 增城市| 太仓市| 柳江县| 大庆市| 郑州市| 武胜县| 永胜县| 志丹县| 抚顺市|