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

java多線程編程必備volatile與synchronized深入理解

 更新時(shí)間:2023年04月12日 10:02:22   作者:玄明Hanko  
這篇文章主要介紹了java多線程編程必備volatile與synchronized的深入理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

Volatile概述

Volatile是Java中的一種輕量級(jí)同步機(jī)制,用于保證變量的可見性和禁止指令重排。當(dāng)一個(gè)變量被聲明為Volatile類型時(shí),任何修改該變量的操作都會(huì)立即被所有線程看到。也就是說,Volatile修飾的變量在每次修改時(shí)都會(huì)強(qiáng)制將修改刷新到主內(nèi)存中,具有很好的可見性和線程安全性。

上圖可以看到在多線程編程中,線程沒有直接操作主內(nèi)存,而是把主內(nèi)存中的數(shù)據(jù)拷貝到工作內(nèi)存中也就是共享變量副本的方式操作變量。當(dāng)一個(gè)變量被多個(gè)線程共享時(shí),如果其中一個(gè)線程修改了這個(gè)變量的值,另一個(gè)線程在讀取這個(gè)變量時(shí)可能會(huì)得到過期的值。這是因?yàn)榫€程之間存在緩存不一致的問題。

使用 volatile 關(guān)鍵字可以解決這個(gè)問題。volatile 保證了對(duì)該變量的訪問都是直接針對(duì)主內(nèi)存中的變量進(jìn)行的,而不是訪問線程本地的緩存。因此,當(dāng)一個(gè)線程修改了這個(gè)變量的值,其他線程能夠立即看到這個(gè)變化,避免了緩存不一致的問題。

具體實(shí)現(xiàn)原理是,在使用 volatile 關(guān)鍵字修飾的變量進(jìn)行讀寫操作時(shí),會(huì)禁止 CPU 的緩存優(yōu)化,每次操作都要直接讀寫主內(nèi)存。同時(shí),在進(jìn)行讀操作時(shí),也會(huì)強(qiáng)制從主內(nèi)存中讀取最新的值,而不是使用線程本地的緩存。這樣就可以保證多線程之間的變量訪問是同步、可見的。

Synchronized概述

Synchronized是Java中的一種重量級(jí)同步機(jī)制,用于保證線程安全和排除數(shù)據(jù)競(jìng)爭(zhēng)。當(dāng)一個(gè)方法被聲明為Synchronized時(shí),同一時(shí)間只有一個(gè)線程可以訪問該方法,其他線程必須等待。這樣可以避免多個(gè)線程同時(shí)訪問共享資源導(dǎo)致數(shù)據(jù)不一致的問題。

Volatile與Synchronized的區(qū)別

(1)Volatile是一種輕量級(jí)的同步機(jī)制,Synchronized是一種重量級(jí)的同步機(jī)制。

(2)Volatile用于保證變量的可見性和禁止指令重排,Synchronized用于排除數(shù)據(jù)競(jìng)爭(zhēng)和保證線程安全。

(3)Volatile不能保證變量的原子性,Synchronized可以保證同步代碼塊的原子性。

(4)Volatile的性能遠(yuǎn)高于Synchronized,但只適用于變量的情況,而Synchronized則適用于任意類型的對(duì)象或代碼塊。

(5)volatile修飾變量,僅用于變量級(jí)(不會(huì)造成線程阻塞),線程讀寫時(shí)均刷新內(nèi)存,只保證可見性。volatile還可以禁止指令重排。

(6)synchronized鎖變量或代碼段,鎖級(jí)(會(huì)造成線程阻塞),能保證可見性與原子性

使用場(chǎng)景

1 Volatile的使用場(chǎng)景

由于Volatile的可見性和禁止指令重排的特點(diǎn),其在一些特定的場(chǎng)景下非常有用,例如:

(1)用于控制線程的開關(guān)、狀態(tài)標(biāo)志、計(jì)數(shù)器等變量;

(2)用于發(fā)布一些不變的對(duì)象,例如單例模式中的實(shí)例;

(3)用于性能調(diào)優(yōu),避免鎖競(jìng)爭(zhēng),例如CAS算法等。

以下是使用Java編寫一個(gè)演示volatile關(guān)鍵字的簡(jiǎn)單示例:

    public class VolatileDemo {
        private volatile boolean isRunning = true;
        public void start() {
            System.out.println("Starting the thread...");
            new Thread(() -> {
                while (isRunning) {
                    // do some work here
                }
                System.out.println("Thread stopped.");
            }).start();
        }
        public void stop() {
            System.out.println("Stopping the thread...");
            isRunning = false;
        }
        public static void main(String[] args) throws InterruptedException {
            VolatileDemo demo = new VolatileDemo();
            demo.start();
            // wait for 3 seconds
            Thread.sleep(3000);
            demo.stop();
        }
    }

在上述示例中,我們創(chuàng)建了一個(gè)名為VolatileDemo的類,并聲明了一個(gè)volatile變量isRunning。此變量用于指示線程是否應(yīng)該繼續(xù)運(yùn)行。在start()方法中,我們啟動(dòng)了一個(gè)新線程,并在while循環(huán)中檢查isRunning變量的值。由于isRunning變量是volatile類型的,因此在不同的線程之間更改它的值時(shí),該值將始終保持同步。在stop()方法中,我們將isRunning變量的值設(shè)置為false,以便使線程停止運(yùn)行。在main()方法中,我們創(chuàng)建了一個(gè)VolatileDemo對(duì)象并調(diào)用start()方法來開始線程的執(zhí)行。然后,我們等待3秒鐘,隨后調(diào)用stop()方法來停止線程的執(zhí)行。由于isRunning變量是volatile類型的,因此線程能夠及時(shí)地檢測(cè)到isRunning變量的更改,從而停止線程的執(zhí)行。

2 Synchronized的使用場(chǎng)景

Synchronized機(jī)制由于其強(qiáng)制性的同步性,在保證線程安全和數(shù)據(jù)完整性的同時(shí),也會(huì)帶來一些性能上的開銷。因此,在使用Synchronized時(shí)需要控制同步的范圍和頻率,適當(dāng)使用Synchronized可以提高程序的效率和可靠性。使用Synchronized的場(chǎng)景包括:

(1)對(duì)共享變量的訪問和修改,例如在多線程情況下對(duì)數(shù)據(jù)進(jìn)行同步處理;

(2)對(duì)類實(shí)例化的構(gòu)造函數(shù)進(jìn)行同步,確保實(shí)例化過程中的線程安全;

(3)對(duì)靜態(tài)變量和方法的訪問和修改,例如在多線程情況下對(duì)靜態(tài)變量進(jìn)行同步。

以下是使用Java編寫一個(gè)演示synchronized關(guān)鍵字的簡(jiǎn)單示例:

public class SynchronizedDemo {
    private int counter = 0;
    public synchronized void increment() {
        counter++;
    }
    public synchronized int getCounter() {
        return counter;
    }
    public static void main(String[] args) throws InterruptedException {
        SynchronizedDemo demo = new SynchronizedDemo();
        // create multiple threads to increment counter
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    demo.increment();
                }
            }).start();
        }
        // wait for all threads to finish
        Thread.sleep(5000);
        // print the final value of counter
        System.out.println("Final value of counter: " + demo.getCounter());
    }
}

在上述示例中,我們創(chuàng)建了一個(gè)名為SynchronizedDemo的類,并聲明了一個(gè)私有變量counter。我們?cè)趇ncrement()方法和getCounter()方法上加了synchronized關(guān)鍵字來確保每次只有一個(gè)線程可以訪問這些方法。

在main()方法中,我們創(chuàng)建了10個(gè)線程來并發(fā)地執(zhí)行increment()方法,每個(gè)線程將計(jì)數(shù)器增加1000次。由于increment()方法是同步的,因此在任何時(shí)候都只有一個(gè)線程可以訪問它,從而避免了數(shù)據(jù)競(jìng)爭(zhēng)和不一致性。

最后,我們等待所有線程完成后打印計(jì)數(shù)器的最終值。由于getCounter()方法也是同步的,所以它返回的值將始終是最新的和正確的。

注意事項(xiàng)

(1)使用Volatile時(shí)需要注意可見性和原子性,不能保證多個(gè)操作的原子性。

(2)使用Synchronized時(shí)需要注意同步塊的范圍和對(duì)象的鎖定,避免死鎖和性能問題。

(3)在多線程編程中,需要根據(jù)實(shí)際情況選擇合適的同步機(jī)制或使用多種同步機(jī)制的組合,以保證程序的正確性和可靠性。

相關(guān)面試問題

  • volatile 和 synchronized 有什么區(qū)別?

答:volatile 關(guān)鍵字只能保證變量的可見性,不能保證原子性以及同步性,而 synchronized 關(guān)鍵字既能保證原子性和同步性,也能保證變量的可見性。

  • volatile 能否替代 synchronized?

答:不能。雖然 volatile 可以保證變量的可見性,但是它無法保證原子性和同步性,而 synchronized 能夠保證這三種特性。

  • synchronized 與 volatile 的實(shí)現(xiàn)機(jī)制有何不同?

答:synchronized 是通過對(duì)對(duì)象或類進(jìn)行加鎖來保證同步性和原子性的,其效率相對(duì)較低;而 volatile 是通過禁止 CPU 緩存優(yōu)化來保證變量的可見性,其開銷相對(duì)較小,但不能保證同步性和原子性。

  • 在什么情況下需要使用 volatile?

答:當(dāng)一個(gè)變量被多個(gè)線程訪問時(shí),可能存在緩存不一致的問題,此時(shí)需要使用 volatile 來保證變量的可見性。

  • synchronized 和 volatile 的適用場(chǎng)景分別是什么?

答:synchronized 適用于保證臨界區(qū)代碼的原子性和同步性,而 volatile 適用于保證變量的可見性。因此,如果需要進(jìn)行復(fù)雜的操作并且需要保證原子性和同步性時(shí),應(yīng)該使用 synchronized;而如果只需要保證變量的可見性時(shí),可以使用 volatile。

以上就是java多線程編程必備volatile與synchronized深入理解的詳細(xì)內(nèi)容,更多關(guān)于java多線程volatile synchronized的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java 中多線程生產(chǎn)者消費(fèi)者問題詳細(xì)介紹

    java 中多線程生產(chǎn)者消費(fèi)者問題詳細(xì)介紹

    這篇文章主要介紹了java 中多線程生產(chǎn)者消費(fèi)者問題詳細(xì)介紹的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • SpringBoot整合mybatis-plus實(shí)現(xiàn)分頁查詢功能

    SpringBoot整合mybatis-plus實(shí)現(xiàn)分頁查詢功能

    這篇文章主要介紹了SpringBoot整合mybatis-plus實(shí)現(xiàn)分頁查詢功能,pringBoot分頁查詢的兩種寫法,一種是手動(dòng)實(shí)現(xiàn),另一種是使用框架實(shí)現(xiàn),現(xiàn)在我將具體的實(shí)現(xiàn)流程分享一下,需要的朋友可以參考下
    2023-11-11
  • SpringBoot使用Nacos配置中心的實(shí)現(xiàn)

    SpringBoot使用Nacos配置中心的實(shí)現(xiàn)

    這篇文章主要介紹了SpringBoot使用Nacos配置中心的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Java編程中避免equals方法的隱藏陷阱介紹

    Java編程中避免equals方法的隱藏陷阱介紹

    這篇文章主要介紹了Java編程中避免equals方法的隱藏陷阱介紹,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • Java實(shí)現(xiàn)限流接口的示例詳解

    Java實(shí)現(xiàn)限流接口的示例詳解

    限流是對(duì)某一時(shí)間窗口內(nèi)的請(qǐng)求數(shù)進(jìn)行限制,保持系統(tǒng)的可用性和穩(wěn)定性,防止因流量暴增而導(dǎo)致的系統(tǒng)運(yùn)行緩慢或宕機(jī),本文主要來和大家聊聊如何使用java實(shí)現(xiàn)限流接口,感興趣的可以了解下
    2023-12-12
  • java中線程安全的list詳細(xì)特性和用法

    java中線程安全的list詳細(xì)特性和用法

    這篇文章主要給大家介紹了關(guān)于java中線程安全的list詳細(xì)特性和用法的相關(guān)資料,Java中有多種線程安全的List,其中比較常用的有Vector、Collections.synchronizedList()和CopyOnWriteArrayList三種方式,需要的朋友可以參考下
    2024-03-03
  • 詳解SSM框架下結(jié)合log4j、slf4j打印日志

    詳解SSM框架下結(jié)合log4j、slf4j打印日志

    本篇文章主要介紹了詳解SSM框架下結(jié)合log4j、slf4j打印日志,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-11-11
  • MyBatisPlus的autoResultMap生成策略實(shí)現(xiàn)

    MyBatisPlus的autoResultMap生成策略實(shí)現(xiàn)

    本文主要介紹了MyBatisPlus的autoResultMap生成策略實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-02-02
  • String字符串拼接方法concat和+的效率對(duì)比

    String字符串拼接方法concat和+的效率對(duì)比

    這篇文章主要介紹了String字符串拼接方法concat和+的效率對(duì)比,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java持久層框架MyBatis簡(jiǎn)單實(shí)例

    Java持久層框架MyBatis簡(jiǎn)單實(shí)例

    MyBatis 本是apache的一個(gè)開源項(xiàng)目iBatis, 2010年這個(gè)項(xiàng)目由apache software foundation 遷移到了google code,并且改名為MyBatis 。本文重點(diǎn)給大家介紹Java持久層框架MyBatis簡(jiǎn)單實(shí)例,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看下吧
    2016-07-07

最新評(píng)論

突泉县| 边坝县| 镇江市| 晋州市| 聂拉木县| 阜阳市| 进贤县| 高尔夫| 临泽县| 钦州市| 昌都县| 玉树县| 赤峰市| 桐乡市| 海阳市| 恩施市| 宿州市| 舟山市| 林甸县| 保德县| 双城市| 资溪县| 饶阳县| 丹凤县| 卢氏县| 江山市| 密山市| 巧家县| 稷山县| 庆安县| 乐山市| 香港 | 宝丰县| 大冶市| 渑池县| 上林县| 承德县| 凯里市| 东乌珠穆沁旗| 大埔县| 瑞丽市|