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

深入理解Java顯式鎖的相關(guān)知識(shí)

 更新時(shí)間:2021年06月23日 14:27:35   作者:IT王小二  
今天帶大家學(xué)習(xí)的是關(guān)于Java的相關(guān)知識(shí),文章圍繞著Java顯式鎖展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下

一、顯式鎖

什么是顯式鎖?

由自己手動(dòng)獲取鎖,然后手動(dòng)釋放的鎖。

有了 synchronized(內(nèi)置鎖) 為什么還要 Lock(顯示鎖)?

使用 synchronized 關(guān)鍵字實(shí)現(xiàn)了鎖功能的,使用 synchronized 關(guān)鍵字將會(huì)隱式地獲取鎖,但是它將鎖的獲取和釋放固化了,也就是先獲取再釋放。

與內(nèi)置加鎖機(jī)制不同的是,Lock 提供了一種無(wú)條件的、可輪詢的、定時(shí)的以及可中斷的鎖獲取操作,所有加鎖和解鎖的方法都是顯式的。

二、Lock的常用api

方法名稱(chēng) 描述
void lock() 獲取鎖
void lockInterruptibly() throws InterruptedException 可中斷的獲取鎖,和lock()方法的不同之處在于該方法會(huì)響應(yīng)中斷,即在鎖的獲取中可以中斷當(dāng)前線程
boolean tryLock() 嘗試非阻塞的獲取鎖,調(diào)用該方法后立刻返回,如果能夠獲取則返回true,否則返回false
boolean tryLock(long time, TimeUnit unit) throws InterruptedException 超時(shí)獲取鎖,當(dāng)前線程會(huì)在以下三種情況下會(huì)返回:
1. 當(dāng)前線程在超時(shí)時(shí)間內(nèi)獲得了鎖
2.當(dāng)前線程在超市時(shí)間內(nèi)被中斷
3. 超時(shí)時(shí)間結(jié)束,返回false
void unlock(); 釋放鎖

三、Lock的標(biāo)準(zhǔn)用法

lock.lock();
try {
    // 業(yè)務(wù)邏輯
} finally {
    lock.unlock();
}
  • 在 finally 塊中釋放鎖,目的是保證在獲取到鎖之后,最終能夠被釋放。
  • 不要將獲取鎖的過(guò)程寫(xiě)在 try 塊中,因?yàn)槿绻讷@取鎖(自定義鎖的實(shí)現(xiàn))時(shí)發(fā)生了異常,異常拋出的同時(shí),也會(huì)導(dǎo)致鎖無(wú)故釋放。

四、ReentrantLock(可重入鎖)

Lock接口常用的實(shí)現(xiàn)類(lèi)是 ReentrantLock。

示例代碼:主線程100000次減,子線程10萬(wàn)次加。

public class ReentrantLockTest {

    private Lock lock = new ReentrantLock();
    private int count = 0;

    public int getCount() {
        return count;
    }

    private static class ReentrantLockThread extends Thread {
        private ReentrantLockTest reentrantLockTest;

        public ReentrantLockThread(ReentrantLockTest reentrantLockTest) {
            this.reentrantLockTest = reentrantLockTest;
        }

        @Override
        public void run() {
            for (int i = 0; i < 100000; i++) {
                reentrantLockTest.incr();
            }
            System.out.println(Thread.currentThread().getName() + " end, count =  " + reentrantLockTest.getCount());
        }
    }

    private void incr() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }

    private void decr() {
        lock.lock();
        try {
            count--;
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ReentrantLockTest reentrantLockTest = new ReentrantLockTest();
        new ReentrantLockThread(reentrantLockTest).start();

        for (int i = 0; i < 100000; i++) {
            // 遞減100000
            reentrantLockTest.decr();
        }
        System.out.println(Thread.currentThread().getName() + " count =  " + reentrantLockTest.getCount());
    }
}

1. 鎖的可重入性

簡(jiǎn)單地講就是:“同一個(gè)線程對(duì)于已經(jīng)獲得到的鎖,可以多次繼續(xù)申請(qǐng)到該鎖的使用權(quán)”。而 synchronized 關(guān)鍵字隱式的支持重進(jìn)入,比如一個(gè) synchronized 修飾的遞歸方法,在方法執(zhí)行時(shí),執(zhí)行線程在獲取了鎖之后仍能連續(xù)多次地獲得該鎖

同樣,ReentrantLock 在調(diào)用 lock()方法時(shí),已經(jīng)獲取到鎖的線程,能夠再次調(diào)用lock()方法獲取鎖而不被阻塞

2. 公平鎖和非公平鎖

  • 如果在時(shí)間上,先對(duì)鎖進(jìn)行獲取的請(qǐng)求一定先被滿足,那么這個(gè)鎖是公平的,反之,是不公平的。公平的獲取鎖,也就是等待時(shí)間最長(zhǎng)的線程最優(yōu)先獲取鎖,也可以說(shuō)鎖獲取是順序的。
  • ReentrantLock 提供了一個(gè)構(gòu)造函數(shù),能夠控制鎖是否是公平的(缺省為不公平鎖)。事實(shí)上,公平的鎖機(jī)制往往沒(méi)有非公平的效率高。
  • 在激烈競(jìng)爭(zhēng)的情況下,非公平鎖的性能高于公平鎖的性能的一個(gè)原因是:在恢復(fù)一個(gè)被掛起的線程與該線程真正開(kāi)始運(yùn)行之間存在著嚴(yán)重的延遲。
  • 假設(shè)線程 A 持有一個(gè)鎖,并且線程 B 請(qǐng)求這個(gè)鎖,由于這個(gè)鎖已被線程 A 持有,因此 B 將被掛起。當(dāng) A 釋放鎖時(shí),B 將被喚醒,因此會(huì)再次嘗試獲取鎖。與此同時(shí),如果 C 也請(qǐng)求這個(gè)鎖,那么 C 很可能會(huì)在 B 被完全喚醒之前獲得、使用以及釋放這個(gè)鎖,這樣的情況是一種“雙贏”的局面:B 獲得鎖的時(shí)刻并沒(méi)有推遲,C 更早地獲得了鎖,完成了自己的任務(wù),然后釋放了鎖,并且吞吐量也獲得了提高。

五、ReentrantReadWriteLock(讀寫(xiě)鎖)

ReentrantReadWriteLock 是 ReadWriteLock 的實(shí)現(xiàn)類(lèi)。

之前提到鎖基本都是排他鎖,這些鎖在同一時(shí)刻只允許一個(gè)線程進(jìn)行訪問(wèn),而讀寫(xiě)鎖在同一時(shí)刻可以允許多個(gè)讀線程訪問(wèn)但是在寫(xiě)線程訪問(wèn)時(shí),所有的讀線程和其他寫(xiě)線程均被阻塞。讀寫(xiě)鎖維護(hù)了一對(duì)鎖,一個(gè)讀鎖和一個(gè)寫(xiě)鎖,通過(guò)分離讀鎖和寫(xiě)鎖,使得并發(fā)性相比一般的排他鎖有了很大提升。

讀鎖不排斥讀鎖,但是排斥寫(xiě)鎖;寫(xiě)鎖即排斥讀鎖也排斥寫(xiě)鎖。

private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock getLock = lock.readLock(); // 讀鎖
private final Lock setLock = lock.writeLock(); // 寫(xiě)鎖

至于上鎖、解鎖與 ReentrantLock 使用方式一致。

六、Condition

  • 任意一個(gè) Java 對(duì)象,都擁有一組監(jiān)視器方法(定義在 java.lang.Object 上),主要包括 wait()、wait(long timeout)、notify()以及 notifyAll()方法,這些方法與 synchronized 同步關(guān)鍵字配合,可以實(shí)現(xiàn)等待/通知模式。
  • Condition 接口也提供了類(lèi)似 Object 的監(jiān)視器方法,與 Lock 配合可以實(shí)現(xiàn)等待/通知模式。

常用api

方法名稱(chēng) 描述
void await() throws InterruptedException 使當(dāng)前線程進(jìn)入等待狀態(tài)直到被通知(signal)或中斷
void signal() 喚醒一個(gè)等待的線程
void signalAll() 喚醒所有等待的線程

示例代碼,主線程調(diào)用方法喚醒兩個(gè)子線程。

public class ConditionTest {

    private volatile boolean flag = false;
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    private void task1() {
        lock.lock();
        try {
            try {
                System.out.println(Thread.currentThread().getName() + " 等待中");
                condition.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " 等待結(jié)束");
            System.out.println("發(fā)送郵件");
        } finally {
            lock.unlock();
        }
    }

    private void task2() {
        lock.lock();
        try {
            try {
                System.out.println(Thread.currentThread().getName() + " 等待中");
                condition.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " 等待結(jié)束");
            System.out.println("發(fā)送短信");
        } finally {
            lock.unlock();
        }
    }

    private void updateFlag() {
        lock.lock();
        try {
            this.flag = true;
            this.condition.signalAll();
        }finally {
            lock.unlock();
        }
    }

    private static class ConditionThread1 extends Thread {
        private ConditionTest conditionTest;
        public ConditionThread1(ConditionTest conditionTest) {
            this.conditionTest = conditionTest;
        }

        @Override
        public void run() {
            if (!conditionTest.flag) {
                conditionTest.task1();
            }
        }
    }

    private static class ConditionThread2 extends Thread {
        private ConditionTest conditionTest;
        public ConditionThread2(ConditionTest conditionTest) {
            this.conditionTest = conditionTest;
        }

        @Override
        public void run() {
            if (!conditionTest.flag) {
                conditionTest.task2();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ConditionTest conditionTest = new ConditionTest();
        new ConditionThread1(conditionTest).start();
        new ConditionThread2(conditionTest).start();
        Thread.sleep(1000);
        System.out.println("flag 改變。。。");
        conditionTest.updateFlag();
    }
}

到此這篇關(guān)于深入理解Java顯式鎖的相關(guān)知識(shí)的文章就介紹到這了,更多相關(guān)Java顯式鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 簡(jiǎn)單實(shí)現(xiàn)Java通訊錄系統(tǒng)

    簡(jiǎn)單實(shí)現(xiàn)Java通訊錄系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了如何簡(jiǎn)單實(shí)現(xiàn)Java通訊錄系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • SpringMvc MultipartFile實(shí)現(xiàn)圖片文件上傳示例

    SpringMvc MultipartFile實(shí)現(xiàn)圖片文件上傳示例

    本篇文章主要介紹了SpringMvc MultipartFile實(shí)現(xiàn)圖片文件上傳示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-02-02
  • Java實(shí)現(xiàn)鼠標(biāo)隨機(jī)移動(dòng)效果的示例代碼

    Java實(shí)現(xiàn)鼠標(biāo)隨機(jī)移動(dòng)效果的示例代碼

    有的時(shí)候我們需要鼠標(biāo)一直滑動(dòng)的情況,為了節(jié)省時(shí)間,本文用Java語(yǔ)言寫(xiě)了一個(gè)腳本,可以實(shí)現(xiàn)鼠標(biāo)隨機(jī)移動(dòng),感興趣的小伙伴可以了解一下
    2022-05-05
  • springboot使用@data注解減少不必要代碼

    springboot使用@data注解減少不必要代碼

    這篇文章主要介紹了springboot使用@data注解減少不必要代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • JavaTCP上傳圖片代碼實(shí)例

    JavaTCP上傳圖片代碼實(shí)例

    今天小編就為大家分享一篇關(guān)于JavaTCP上傳圖片代碼實(shí)例,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-02-02
  • Zookeeper啟動(dòng)指定JDK版本方式

    Zookeeper啟動(dòng)指定JDK版本方式

    文章講述了如何在Linux系統(tǒng)上啟動(dòng)指定JDK版本的Zookeeper,包括下載JDK、解壓文件、修改zkEnv.sh腳本和重啟Zookeeper的過(guò)程
    2025-02-02
  • java統(tǒng)計(jì)文件中每個(gè)字符出現(xiàn)的個(gè)數(shù)

    java統(tǒng)計(jì)文件中每個(gè)字符出現(xiàn)的個(gè)數(shù)

    這篇文章主要為大家詳細(xì)介紹了java統(tǒng)計(jì)文件中每個(gè)字符出現(xiàn)的個(gè)數(shù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • Java 抽象類(lèi)與接口的對(duì)比

    Java 抽象類(lèi)與接口的對(duì)比

    這篇文章主要介紹了Java 抽象類(lèi)與接口的對(duì)比,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下
    2020-08-08
  • 解決Java項(xiàng)目中request流只能獲取一次的問(wèn)題

    解決Java項(xiàng)目中request流只能獲取一次的問(wèn)題

    Java項(xiàng)目開(kāi)發(fā)中可能存在以下幾種情況,你需要在攔截器中統(tǒng)一攔截請(qǐng)求和你項(xiàng)目里可能需要搞一個(gè)統(tǒng)一的異常處理器,這兩種情況是比較常見(jiàn)的,本文將給大家介紹如何解決Java項(xiàng)目中request流只能獲取一次的問(wèn)題,需要的朋友可以參考下
    2024-02-02
  • Java WebService 簡(jiǎn)單實(shí)例(附實(shí)例代碼)

    Java WebService 簡(jiǎn)單實(shí)例(附實(shí)例代碼)

    本篇文章主要介紹了Java WebService 簡(jiǎn)單實(shí)例(附實(shí)例代碼), Web Service 是一種新的web應(yīng)用程序分支,他們是自包含、自描述、模塊化的應(yīng)用,可以發(fā)布、定位、通過(guò)web調(diào)用。有興趣的可以了解一下
    2017-01-01

最新評(píng)論

长春市| 南木林县| 开封县| 获嘉县| 潞城市| 克拉玛依市| 石阡县| 慈溪市| 西宁市| 鲁山县| 库尔勒市| 措美县| 运城市| 济宁市| 疏勒县| 德清县| 鹤壁市| 长宁县| 磴口县| 新郑市| 大理市| 娱乐| 宁武县| 朝阳市| 泰顺县| 齐齐哈尔市| 东兰县| 砚山县| 本溪市| 江源县| 沙河市| 中超| 临猗县| 博客| 汉中市| 洛川县| 清苑县| 和政县| 墨江| 河东区| 安多县|