欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java并發(fā)鎖的實(shí)現(xiàn)

 更新時(shí)間:2024年04月11日 09:23:20   作者:Flying_Fish_roe  
Java中的鎖主要是為了解決多個(gè)線(xiàn)程訪問(wèn)共享數(shù)據(jù)時(shí)的競(jìng)爭(zhēng)問(wèn)題,確保線(xiàn)程能夠安全地訪問(wèn)和修改共享數(shù)據(jù),本文主要介紹了java并發(fā)鎖的實(shí)現(xiàn),感興趣的可以了解一下

ReentrantLock 

ReentrantLock是Java并發(fā)編程中的一種鎖機(jī)制。它的基本流程如下:

  • 創(chuàng)建ReentrantLock對(duì)象。
  • 在需要加鎖的代碼塊前調(diào)用lock()方法,該方法會(huì)嘗試獲取鎖,如果鎖已被其他線(xiàn)程占用,則當(dāng)前線(xiàn)程會(huì)被阻塞。
  • 執(zhí)行需要加鎖的代碼。
  • 在加鎖代碼塊的finally語(yǔ)句塊中調(diào)用unlock()方法來(lái)釋放鎖。

ReentrantLock的特點(diǎn)和用法如下:

  • 可重入性:ReentrantLock是可重入鎖,即同一個(gè)線(xiàn)程可以重復(fù)獲取該鎖,而不會(huì)發(fā)生死鎖。這是通過(guò)維護(hù)一個(gè)持有鎖的線(xiàn)程的引用計(jì)數(shù)來(lái)實(shí)現(xiàn)的。
  • 公平性:ReentrantLock可以指定是公平鎖還是非公平鎖,默認(rèn)情況下是非公平鎖。公平鎖是按照線(xiàn)程申請(qǐng)鎖的順序來(lái)分配鎖,而非公平鎖則是隨機(jī)分配鎖,可能會(huì)導(dǎo)致某些線(xiàn)程饑餓。
  • 條件變量:ReentrantLock提供了Condition接口的實(shí)現(xiàn),可以通過(guò)該接口實(shí)現(xiàn)對(duì)線(xiàn)程的等待和喚醒機(jī)制,更靈活地控制線(xiàn)程的同步。
  • 可中斷:ReentrantLock提供了lockInterruptibly()方法,如果當(dāng)前線(xiàn)程還沒(méi)有獲取到鎖,但是被其他線(xiàn)程中斷,可以通過(guò)該方法響應(yīng)中斷。

以下是一個(gè)使用ReentrantLock的Java代碼示例:

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockExample {
    private static ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) {
        // 創(chuàng)建并啟動(dòng)多個(gè)線(xiàn)程
        for (int i = 0; i < 5; i++) {
            Thread thread = new Thread(new MyThread());
            thread.start();
        }
    }

    static class MyThread implements Runnable {
        @Override
        public void run() {
            try {
                // 加鎖
                lock.lock();
                // 執(zhí)行需要加鎖的代碼
                System.out.println("Thread " + Thread.currentThread().getId() + " is running");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                // 釋放鎖
                lock.unlock();
            }
        }
    }
}

在上述示例中,我們創(chuàng)建了一個(gè)ReentrantLock對(duì)象,并在MyThread的run()方法中加鎖、執(zhí)行代碼、釋放鎖。在main方法中,我們創(chuàng)建并啟動(dòng)了5個(gè)線(xiàn)程,它們會(huì)依次獲取鎖并執(zhí)行代碼。由于ReentrantLock是可重入鎖,同一個(gè)線(xiàn)程可以多次獲取鎖,所以每個(gè)線(xiàn)程都可以成功地執(zhí)行代碼塊。

ReentrantReadWriteLock

ReentrantReadWriteLock是Java并發(fā)編程中的一個(gè)鎖機(jī)制,它是一種讀寫(xiě)鎖,允許多個(gè)線(xiàn)程同時(shí)讀共享資源,但只能有一個(gè)線(xiàn)程寫(xiě)資源。ReentrantReadWriteLock在實(shí)現(xiàn)上通過(guò)兩個(gè)鎖來(lái)實(shí)現(xiàn),一個(gè)是讀鎖(共享鎖),一個(gè)是寫(xiě)鎖(獨(dú)占鎖)。

基本流程如下:

  • 多個(gè)線(xiàn)程可以同時(shí)獲取讀鎖,讀鎖之間不互斥,可以并發(fā)執(zhí)行。
  • 獲取寫(xiě)鎖的線(xiàn)程會(huì)阻塞其他線(xiàn)程的讀鎖和寫(xiě)鎖,只有釋放寫(xiě)鎖后才允許其他線(xiàn)程獲取讀寫(xiě)鎖。

ReentrantReadWriteLock的特點(diǎn)和用法:

  • 公平性:可以選擇公平模式或非公平模式,默認(rèn)是非公平模式。在非公平模式下,允許鎖被后來(lái)的線(xiàn)程插隊(duì),以提高吞吐量;在公平模式下,鎖會(huì)按照請(qǐng)求的順序分配給線(xiàn)程,保證公平性。
  • 重入性:與ReentrantLock一樣,ReentrantReadWriteLock可以重入,同一個(gè)線(xiàn)程可以多次獲取讀鎖或?qū)戞i。
  • 鎖降級(jí):一個(gè)線(xiàn)程擁有寫(xiě)鎖的時(shí)候,可以先獲取讀鎖,然后再釋放寫(xiě)鎖,這樣就實(shí)現(xiàn)了鎖的降級(jí)。
  • 鎖升級(jí):讀鎖不能升級(jí)為寫(xiě)鎖,因?yàn)闀?huì)有死鎖的風(fēng)險(xiǎn)。

下面是一個(gè)簡(jiǎn)單的示例代碼,展示了ReentrantReadWriteLock的用法:

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class MyReadWriteLock {
    private int value = 0;
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public int getValue() {
        lock.readLock().lock(); // 獲取讀鎖
        try {
            return value;
        } finally {
            lock.readLock().unlock(); // 釋放讀鎖
        }
    }

    public void increment() {
        lock.writeLock().lock(); // 獲取寫(xiě)鎖
        try {
            value++;
        } finally {
            lock.writeLock().unlock(); // 釋放寫(xiě)鎖
        }
    }
}

在上面的示例中,MyReadWriteLock類(lèi)包含一個(gè)value變量和一個(gè)ReentrantReadWriteLock對(duì)象。getValue()方法獲取讀鎖,讀取value的值并返回。increment()方法獲取寫(xiě)鎖,將value加1。通過(guò)使用讀寫(xiě)鎖,多個(gè)線(xiàn)程可以同時(shí)讀取value的值,但只有一個(gè)線(xiàn)程可以寫(xiě)入value的值。

Condition

Condition是Java并發(fā)編程中的一種同步機(jī)制,它可以用于實(shí)現(xiàn)線(xiàn)程之間的等待和通知。

基本流程:

  • 創(chuàng)建一個(gè)Lock對(duì)象,通過(guò)Lock對(duì)象的newCondition()方法創(chuàng)建一個(gè)Condition對(duì)象。
  • 通過(guò)Lock對(duì)象的lock()方法獲取鎖。
  • 在某個(gè)線(xiàn)程中,通過(guò)Condition對(duì)象的await()方法使線(xiàn)程等待,同時(shí)釋放鎖。
  • 在另一個(gè)線(xiàn)程中,通過(guò)Condition對(duì)象的signal()或signalAll()方法進(jìn)行通知。
  • 在第一個(gè)線(xiàn)程中,通過(guò)Condition對(duì)象的await()方法再次獲取鎖并繼續(xù)執(zhí)行。

特點(diǎn)和用法:

  • 可以與Lock對(duì)象配合使用,對(duì)某個(gè)共享資源進(jìn)行互斥訪問(wèn)和條件等待。
  • 可以精確地控制線(xiàn)程的等待和通知。

示例代碼:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionExample {
    private final Lock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
    private boolean flag = false;

    public void waitForFlag() throws InterruptedException {
        lock.lock();
        try {
            while (!flag) {
                condition.await(); // 線(xiàn)程等待并釋放鎖
            }
        } finally {
            lock.unlock();
        }
        System.out.println("Flag is true, continue executing.");
    }

    public void setFlag() {
        lock.lock();
        try {
            flag = true;
            condition.signalAll(); // 發(fā)送通知并喚醒等待線(xiàn)程
        } finally {
            lock.unlock();
        }
    }

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

        Thread waitingThread = new Thread(() -> {
            try {
                example.waitForFlag();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread settingThread = new Thread(() -> {
            try {
                Thread.sleep(2000); // 模擬執(zhí)行耗時(shí)操作
                example.setFlag();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        waitingThread.start();
        settingThread.start();

        waitingThread.join();
        settingThread.join();
    }
}

在上述示例中,有兩個(gè)線(xiàn)程,一個(gè)線(xiàn)程等待flag變量為true,另一個(gè)線(xiàn)程在某一時(shí)刻將flag設(shè)置為true。通過(guò)Condition對(duì)象的await()方法使等待線(xiàn)程進(jìn)入等待狀態(tài),并釋放鎖,直到另一個(gè)線(xiàn)程通過(guò)Condition對(duì)象的signalAll()方法發(fā)送通知并喚醒等待線(xiàn)程,等待線(xiàn)程再次獲取鎖并繼續(xù)執(zhí)行。

應(yīng)用場(chǎng)景

不同的鎖機(jī)制應(yīng)對(duì)的問(wèn)題不同,在使用時(shí)需要根據(jù)具體的應(yīng)用場(chǎng)景進(jìn)行選擇。

  • synchronized 鎖適用于互斥場(chǎng)景,代碼粒度小,適合在單線(xiàn)程或少量并發(fā)的情況下使用。

  • Lock 鎖適用于復(fù)雜的并發(fā)場(chǎng)景,通過(guò)支持公平性、可中斷等待鎖等特點(diǎn),提高了系統(tǒng)的性能。

  • ReentrantLock 鎖是 Lock 接口的實(shí)現(xiàn)類(lèi),支持可重入、可中斷等待等特點(diǎn),適用于異步線(xiàn)程操作。

  • ReadWriteLock 鎖適用于讀寫(xiě)性能比較高的場(chǎng)景,在讀多寫(xiě)少的情況下可以提高并發(fā)性能。

  • StampedLock 鎖適用于讀多寫(xiě)少的場(chǎng)景,在使用時(shí)需要根據(jù)實(shí)際場(chǎng)景選擇樂(lè)觀鎖或悲觀鎖,提高了并發(fā)性能。

總結(jié) 

Java并發(fā)體系中的鎖是用來(lái)管理多個(gè)線(xiàn)程對(duì)共享資源的訪問(wèn)的工具。鎖的使用可以確保多個(gè)線(xiàn)程之間的同步和互斥,從而避免競(jìng)態(tài)條件和數(shù)據(jù)的不一致性。

Java中的鎖可以分為兩大類(lèi):內(nèi)置鎖和顯式鎖。

內(nèi)置鎖:

  • synchronized關(guān)鍵字:synchronized是Java中最基本的內(nèi)置鎖機(jī)制。它可以修飾方法或代碼塊,一次只允許一個(gè)線(xiàn)程訪問(wèn)被修飾的代碼塊或方法。當(dāng)一個(gè)線(xiàn)程獲得鎖時(shí),其他線(xiàn)程必須等待鎖釋放才能繼續(xù)執(zhí)行。
  • 鎖對(duì)象:synchronized還可以用于指定一個(gè)對(duì)象作為鎖。當(dāng)一個(gè)線(xiàn)程獲得該對(duì)象的鎖時(shí),其他線(xiàn)程對(duì)該對(duì)象的訪問(wèn)將被阻塞。這種方式可以實(shí)現(xiàn)更細(xì)粒度的鎖控制。

顯式鎖:

  • ReentrantLock類(lèi):ReentrantLock是Java提供的顯式鎖的實(shí)現(xiàn)類(lèi)。它提供了與synchronized類(lèi)似的功能,但提供了更靈活的鎖控制。通過(guò)lock()方法獲取鎖,通過(guò)unlock()方法釋放鎖。ReentrantLock還提供了一些其他功能,如可中斷鎖、公平鎖等。
  • Condition接口:Condition接口是與顯式鎖ReentrantLock配合使用的重要組件。它可以讓線(xiàn)程在等待某個(gè)條件滿(mǎn)足時(shí)暫時(shí)釋放鎖,從而避免了線(xiàn)程一直占用鎖資源而無(wú)法執(zhí)行其他任務(wù)。

鎖的選擇應(yīng)根據(jù)具體的需求和場(chǎng)景來(lái)決定。synchronized是最簡(jiǎn)單和常用的鎖機(jī)制,適用于大部分情況。ReentrantLock提供了更多的靈活性和高級(jí)功能,例如可中斷鎖、公平鎖等,但使用起來(lái)相對(duì)復(fù)雜一些。在多個(gè)線(xiàn)程需要等待某個(gè)條件滿(mǎn)足時(shí),使用Condition接口可以更好地控制線(xiàn)程的等待和喚醒。

到此這篇關(guān)于java并發(fā)鎖的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)java并發(fā)鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Springmvc ajax跨域請(qǐng)求處理方法實(shí)例詳解

    Springmvc ajax跨域請(qǐng)求處理方法實(shí)例詳解

    這篇文章主要介紹了Springmvc ajax跨域請(qǐng)求處理方法實(shí)例詳解,需要的朋友可以參考下
    2017-10-10
  • Java如何獲取List<String>中的String詳解

    Java如何獲取List<String>中的String詳解

    工作了這么長(zhǎng)時(shí)間了,一直沒(méi)有記錄的習(xí)慣,以至于導(dǎo)致我即便是查過(guò)的東西總會(huì)忘記,下面這篇文章主要給大家介紹了關(guān)于Java如何獲取List<String>中String的相關(guān)資料,需要的朋友可以參考下
    2022-02-02
  • java開(kāi)發(fā)AOP基礎(chǔ)JdkDynamicAopProxy

    java開(kāi)發(fā)AOP基礎(chǔ)JdkDynamicAopProxy

    這篇文章主要為大家介紹了java開(kāi)發(fā)AOP基礎(chǔ)JdkDynamicAopProxy源碼示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • java的引用類(lèi)型的詳細(xì)介紹

    java的引用類(lèi)型的詳細(xì)介紹

    在java中提供了4個(gè)級(jí)別的引用:強(qiáng)引用、軟引用、弱引用、虛引用。其中強(qiáng)引用FinalReference是default個(gè)飾符來(lái)修飾,其它3個(gè)級(jí)別均為public修飾
    2013-10-10
  • java 進(jìn)程是如何在Linux服務(wù)器上進(jìn)行內(nèi)存分配的

    java 進(jìn)程是如何在Linux服務(wù)器上進(jìn)行內(nèi)存分配的

    這篇文章主要介紹了java 進(jìn)程是如何在Linux服務(wù)器上進(jìn)行內(nèi)存分配的,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-11-11
  • Springboot中用 Netty 開(kāi)啟UDP服務(wù)方式

    Springboot中用 Netty 開(kāi)啟UDP服務(wù)方式

    這篇文章主要介紹了Springboot中用 Netty 開(kāi)啟UDP服務(wù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • MyBatis-Plus中Service接口的lambdaUpdate用法及實(shí)例分析

    MyBatis-Plus中Service接口的lambdaUpdate用法及實(shí)例分析

    本文將詳細(xì)講解MyBatis-Plus中的lambdaUpdate用法,并提供豐富的案例來(lái)幫助讀者更好地理解和應(yīng)用該特性,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • java JSON解析庫(kù)Alibaba Fastjson用法詳解

    java JSON解析庫(kù)Alibaba Fastjson用法詳解

    這篇文章主要介紹了java JSON解析庫(kù)Alibaba Fastjson用法,結(jié)合實(shí)例形式詳細(xì)分析了java JSON解析庫(kù)Alibaba Fastjson的基本功能、原理、用法及操作注意事項(xiàng),需要的朋友可以參考下
    2020-04-04
  • BufferedReader中read()方法和readLine()方法的使用

    BufferedReader中read()方法和readLine()方法的使用

    這篇文章主要介紹了BufferedReader中read()方法和readLine()方法的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Java中SpringBoot自定義Starter詳解

    Java中SpringBoot自定義Starter詳解

    這篇文章主要介紹了Java中SpringBoot自定義Starter詳解,Starter是Spring Boot中的一個(gè)非常重要的概念,Starter相當(dāng)于模塊,它能將模塊所需的依賴(lài)整合起來(lái)并對(duì)模塊內(nèi)的Bean根據(jù)環(huán)境進(jìn)行自動(dòng)配置,需要的朋友可以參考下
    2023-07-07

最新評(píng)論