偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Synchronized 底層原理與 Lock 的核心區(qū)別

開發(fā) 前端
Lock是Java 5引入的接口(位于java.util.concurrent.locks包),通過API層面實(shí)現(xiàn)線程同步,其核心實(shí)現(xiàn)類為ReentrantLock。Lock的底層依賴?AQS(AbstractQueuedSynchronizer)框架。

前言

圖片圖片

在Java并發(fā)編程中,synchronized和Lock是實(shí)現(xiàn)線程同步的兩大核心機(jī)制。理解它們的底層原理和核心區(qū)別,對(duì)于編寫高效、安全的并發(fā)代碼至關(guān)重要。

synchronized 底層原理

對(duì)象頭與 Mark Word

在Java中,每個(gè)對(duì)象都有一個(gè) 對(duì)象頭(Object Header),其中包含Mark Word和類型指針。Mark Word是實(shí)現(xiàn)synchronized的關(guān)鍵,它存儲(chǔ)了對(duì)象的鎖狀態(tài)、HashCode、GC年齡等信息。

不同鎖狀態(tài)下,Mark Word 的結(jié)構(gòu)不同:

  • 無(wú)鎖狀態(tài):存儲(chǔ)對(duì)象的HashCode和GC年齡。
  • 偏向鎖狀態(tài):存儲(chǔ)偏向線程ID,表明該對(duì)象長(zhǎng)期被某一線程獨(dú)占。
  • 輕量級(jí)鎖狀態(tài):存儲(chǔ)指向線程棧中鎖記錄的指針。
  • 重量級(jí)鎖狀態(tài):存儲(chǔ)指向Monitor鎖的指針。

Monitor 鎖機(jī)制

當(dāng)synchronized升級(jí)到重量級(jí)鎖時(shí),會(huì)依賴Monitor鎖(也稱為管程)。Monitor 是一種同步工具,本質(zhì)是操作系統(tǒng)提供的互斥鎖(Mutex),通過控制線程的阻塞與喚醒實(shí)現(xiàn)同步。

Monitor的核心結(jié)構(gòu)包括:

  • Owner:指向當(dāng)前持有鎖的線程。
  • EntryList:存儲(chǔ)等待獲取鎖的線程隊(duì)列。
  • WaitSet:存儲(chǔ)調(diào)用wait()方法后釋放鎖的線程隊(duì)列。

線程獲取Monitor鎖的流程:

  • 線程嘗試獲取鎖,若Owner為空,則直接占有鎖并將Owner指向自己。
  • 若鎖已被其他線程占有,則當(dāng)前線程進(jìn)入EntryList阻塞等待。
  • 當(dāng)Owner線程釋放鎖時(shí),會(huì)喚醒EntryList中的線程重新競(jìng)爭(zhēng)鎖。

鎖升級(jí)策略

為減少鎖競(jìng)爭(zhēng)帶來的性能損耗,JVM引入了 鎖升級(jí) 機(jī)制,從低開銷的鎖狀態(tài)逐步升級(jí)到高開銷狀態(tài):

  • 偏向鎖:適用于單線程重復(fù)獲取鎖的場(chǎng)景。線程首次獲取鎖時(shí),Mark Word記錄線程ID,后續(xù)該線程可直接獲取鎖,無(wú)需競(jìng)爭(zhēng)。
  • 輕量級(jí)鎖:當(dāng)有其他線程競(jìng)爭(zhēng)鎖時(shí),偏向鎖升級(jí)為輕量級(jí)鎖。線程通過CAS操作將Mark Word中的鎖記錄指針指向自己的棧幀,避免進(jìn)入內(nèi)核態(tài)阻塞。
  • 重量級(jí)鎖:若輕量級(jí)鎖競(jìng)爭(zhēng)激烈(多線程頻繁CAS失?。?,則升級(jí)為重量級(jí)鎖。此時(shí)依賴Monitor鎖,線程會(huì)進(jìn)入內(nèi)核態(tài)阻塞,性能開銷較大。

Lock 的核心實(shí)現(xiàn)

Lock是Java 5引入的接口(位于java.util.concurrent.locks包),通過API層面實(shí)現(xiàn)線程同步,其核心實(shí)現(xiàn)類為ReentrantLock。Lock的底層依賴 AQS(AbstractQueuedSynchronizer)框架。

AQS 核心原理

AQS是并發(fā)工具的基礎(chǔ)框架,通過同步狀態(tài)和雙向阻塞隊(duì)列實(shí)現(xiàn)鎖的獲取與釋放:

  • 同步狀態(tài)(state):用volatile int變量存儲(chǔ)鎖的狀態(tài)(0表示未鎖定,大于0表示已鎖定,支持可重入)。
  • 雙向阻塞隊(duì)列:存儲(chǔ)等待獲取鎖的線程,通過FIFO原則保證線程公平性(可選)。

線程獲取鎖的流程(以 ReentrantLock 為例):

  • 調(diào)用lock()方法時(shí),線程嘗試通過CAS操作修改state:

若state=0,修改為1并成功獲取鎖。

若state>0且當(dāng)前線程是鎖持有者(可重入),則state加1。

若獲取失敗,線程進(jìn)入雙向隊(duì)列阻塞等待。

  • 調(diào)用unlock()方法時(shí),線程減少state值:
  • 若state減為0,釋放鎖并喚醒隊(duì)列中的線程。

Lock 的核心特性

Lock接口定義了比synchronized更靈活的同步操作,核心方法包括:

  • lock():獲取鎖,若未獲取則阻塞。
  • lockInterruptibly():可中斷地獲取鎖,允許線程響應(yīng)中斷。
  • tryLock():嘗試非阻塞獲取鎖,成功返回true。
  • tryLock(long time, TimeUnit unit):超時(shí)獲取鎖。
  • unlock():釋放鎖(需手動(dòng)調(diào)用,通常配合try-finally)。
  • newCondition():創(chuàng)建條件變量,實(shí)現(xiàn)線程間的精細(xì)化通信。

synchronized 與 Lock 的核心區(qū)別

對(duì)比維度

synchronized

Lock

實(shí)現(xiàn)層面

JVM 內(nèi)置關(guān)鍵字,依賴底層字節(jié)碼指令(monitorenter/monitorexit)

Java 類庫(kù)接口,基于 AQS 框架實(shí)現(xiàn)

鎖的獲取與釋放

自動(dòng)獲取與釋放(由 JVM 控制)

手動(dòng)獲取與釋放(需顯式調(diào)用 lock()/unlock(),建議用 try-finally 確保釋放)

可中斷性

不可中斷,一旦阻塞無(wú)法響應(yīng)中斷

可中斷(lockInterruptibly())

超時(shí)獲取

不支持

支持(tryLock(long time, TimeUnit unit))

公平性

非公平鎖(無(wú)法設(shè)置)

可選擇公平鎖或非公平鎖(構(gòu)造函數(shù)參數(shù)控制)

條件變量

僅支持一個(gè)條件變量(通過 wait()/notify() 實(shí)現(xiàn))

支持多個(gè)條件變量(newCondition() 創(chuàng)建)

性能

低競(jìng)爭(zhēng)場(chǎng)景下性能優(yōu)異(鎖升級(jí)優(yōu)化);高競(jìng)爭(zhēng)場(chǎng)景下略遜于 Lock

高競(jìng)爭(zhēng)場(chǎng)景下性能更穩(wěn)定(減少內(nèi)核態(tài)阻塞開銷)

可重入性

支持(同一線程可重復(fù)獲取鎖)

支持(ReentrantLock 是可重入鎖)

使用案例

synchronized 使用案例

同步方法:
public class SynchronizedMethodExample {
    private int count = 0;

    // 同步實(shí)例方法,鎖為當(dāng)前對(duì)象
    public synchronized void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }

    public static void main(String[] args) throws InterruptedException {
        SynchronizedMethodExample example = new SynchronizedMethodExample();
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });
        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        System.out.println("Count: " + example.getCount()); // 輸出 2000
    }
}
同步代碼塊:
public class SynchronizedBlockExample {
    private int count = 0;
    private Object lock = new Object();

    public void increment() {
        // 同步代碼塊,鎖為lock對(duì)象
        synchronized (lock) {
            count++;
        }
    }

    public int getCount() {
        return count;
    }

    public static void main(String[] args) throws InterruptedException {
        SynchronizedBlockExample example = new SynchronizedBlockExample();
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });
        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        System.out.println("Count: " + example.getCount()); // 輸出 2000
    }
}

Lock 使用案例

基本使用:
public class LockBasicExample {
    private int count = 0;
    private Lock lock = new ReentrantLock();

    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }

    public int getCount() {
        return count;
    }

    public static void main(String[] args) throws InterruptedException {
        LockBasicExample example = new LockBasicExample();
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });
        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        System.out.println("Count: " + example.getCount()); // 輸出 2000
    }
}
可中斷鎖:
public class InterruptibleLockExample {
    private Lock lock = new ReentrantLock();

    public void doTask() {
        try {
            // 可中斷地獲取鎖
            lock.lockInterruptibly();
            try {
                System.out.println(Thread.currentThread().getName() + " 獲取到鎖,開始執(zhí)行任務(wù)");
                Thread.sleep(5000);
            } finally {
                lock.unlock();
                System.out.println(Thread.currentThread().getName() + " 釋放鎖");
            }
        } catch (InterruptedException e) {
            System.out.println(Thread.currentThread().getName() + " 被中斷,未能獲取鎖");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        InterruptibleLockExample example = new InterruptibleLockExample();
        Thread thread1 = new Thread(example::doTask, "Thread-1");
        Thread thread2 = new Thread(example::doTask, "Thread-2");

        thread1.start();
        Thread.sleep(1000); // 確保thread1先獲取到鎖
        thread2.start();
        Thread.sleep(1000);
        thread2.interrupt(); // 中斷thread2
    }
}
超時(shí)獲取鎖:
public class TimeoutLockExample {
    private Lock lock = new ReentrantLock();

    public void doTask() {
        try {
            // 超時(shí)獲取鎖,最多等待2秒
            if (lock.tryLock(2, TimeUnit.SECONDS)) {
                try {
                    System.out.println(Thread.currentThread().getName() + " 獲取到鎖,開始執(zhí)行任務(wù)");
                    Thread.sleep(3000);
                } finally {
                    lock.unlock();
                    System.out.println(Thread.currentThread().getName() + " 釋放鎖");
                }
            } else {
                System.out.println(Thread.currentThread().getName() + " 超時(shí)未獲取到鎖");
            }
        } catch (InterruptedException e) {
            System.out.println(Thread.currentThread().getName() + " 被中斷");
        }
    }

    public static void main(String[] args) {
        TimeoutLockExample example = new TimeoutLockExample();
        Thread thread1 = new Thread(example::doTask, "Thread-1");
        Thread thread2 = new Thread(example::doTask, "Thread-2");

        thread1.start();
        thread2.start();
    }
}
多條件變量:
public class MultiConditionExample {
    private Lock lock = new ReentrantLock();
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private boolean flag1 = false;
    private boolean flag2 = false;

    public void waitForCondition1() throws InterruptedException {
        lock.lock();
        try {
            while (!flag1) {
                condition1.await();
            }
            System.out.println(Thread.currentThread().getName() + " 條件1滿足,執(zhí)行操作");
        } finally {
            lock.unlock();
        }
    }

    public void waitForCondition2() throws InterruptedException {
        lock.lock();
        try {
            while (!flag2) {
                condition2.await();
            }
            System.out.println(Thread.currentThread().getName() + " 條件2滿足,執(zhí)行操作");
        } finally {
            lock.unlock();
        }
    }

    public void signalCondition1() {
        lock.lock();
        try {
            flag1 = true;
            condition1.signal();
            System.out.println("喚醒等待條件1的線程");
        } finally {
            lock.unlock();
        }
    }

    public void signalCondition2() {
        lock.lock();
        try {
            flag2 = true;
            condition2.signal();
            System.out.println("喚醒等待條件2的線程");
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MultiConditionExample example = new MultiConditionExample();

        Thread threadA = new Thread(() -> {
            try {
                example.waitForCondition1();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "Thread-A");

        Thread threadB = new Thread(() -> {
            try {
                example.waitForCondition2();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "Thread-B");

        threadA.start();
        threadB.start();

        Thread.sleep(1000);
        example.signalCondition1();
        Thread.sleep(1000);
        example.signalCondition2();
    }
}

責(zé)任編輯:武曉燕 來源: 一安未來
相關(guān)推薦

2025-09-15 07:35:04

Spring容器接口

2021-01-08 08:34:09

Synchronize線程開發(fā)技術(shù)

2022-12-26 09:27:48

Java底層monitor

2024-03-15 15:12:27

關(guān)鍵字底層代碼

2020-06-24 09:35:50

SpringSpring BooJava

2025-05-09 01:30:00

JavaScript事件循環(huán)基石

2024-02-26 07:36:09

lockJava語(yǔ)言

2024-10-06 12:40:26

2022-10-28 10:23:27

Java多線程底層

2024-08-28 08:00:00

2019-05-27 08:11:13

高并發(fā)Synchronize底層

2012-07-12 09:31:06

虛擬化

2012-05-23 19:23:04

云計(jì)算虛擬化

2017-12-06 16:28:48

Synchronize實(shí)現(xiàn)原理

2015-09-06 08:59:52

Java延時(shí)實(shí)例

2024-03-07 07:47:04

代碼塊Monitor

2015-11-16 11:17:30

PHP底層運(yùn)行機(jī)制原理

2022-04-13 14:43:05

JVM同步鎖Monitor 監(jiān)視

2021-08-02 07:57:03

SynchronizeJava語(yǔ)言

2021-08-24 10:25:19

thisclassJava
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)