国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

并發(fā)編程之三大特性及JMM內(nèi)存模型

這篇具有很好參考價(jià)值的文章主要介紹了并發(fā)編程之三大特性及JMM內(nèi)存模型。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

目錄

原子性

如何保證原子性

可見(jiàn)性

如何保證可見(jiàn)性

有序性

如何保證有序性

Java內(nèi)存模型(JMM內(nèi)存模型)

Java內(nèi)存模型的一些關(guān)鍵概念:

主內(nèi)存與工作內(nèi)存交互協(xié)議

Java內(nèi)存模型通過(guò)以下手段來(lái)確保多線(xiàn)程程序的正確性:

鎖機(jī)制

volatile

volatile禁止指令重排序

?Happens-Before


并發(fā)三大特性

原子性、可見(jiàn)性、有序性

原子性

? ? ? ? 原子性是指一個(gè)操作是不可中斷的。一個(gè)原子操作是一個(gè)不可分割的整體,要么全部執(zhí)行成功,要么全部不執(zhí)行。在多線(xiàn)程環(huán)境下,當(dāng)多個(gè)線(xiàn)程訪(fǎng)問(wèn)共享變量時(shí),如果其中一個(gè)線(xiàn)程在執(zhí)行某個(gè)操作,其他線(xiàn)程不能同時(shí)執(zhí)行該操作。

public class AtomicTest {
    private static volatile int counter = 0;

    public static void main(String[] args) {

        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(() -> {
                for (int j = 0; j < 10000; j++) {
                    //synchronized (AtomicTest.class) {
                        counter++;
                   // }
                }
            });
            thread.start();
        }
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(counter);
    }
}

? ? ? ? 正常執(zhí)行后counter變量的值遠(yuǎn)遠(yuǎn)大于預(yù)期10000,加synchronized后counter變量為10000

如何保證原子性

? ? ? 1. 通過(guò)synchronized關(guān)鍵字保證原子性

? ? ? 2. 通過(guò) Lock鎖保證原子性

? ? ? 3. 通過(guò) CAS保證原子性


可見(jiàn)性

? ? ? ?可見(jiàn)性是指當(dāng)一個(gè)線(xiàn)程修改了共享變量的值時(shí),其他線(xiàn)程能夠立即看到這個(gè)修改。在多線(xiàn)程環(huán)境下,由于線(xiàn)程之間的緩存機(jī)制,一個(gè)線(xiàn)程對(duì)共享變量的修改可能不會(huì)立即被其他線(xiàn)程看到。

?

public class VisibilityExample {
    private static boolean stop = false;

    public static void main(String[] args) {
        // 線(xiàn)程1:修改共享變量
        Thread thread1 = new Thread(() -> {
            while (!stop) {
                // do something
            }
            System.out.println("Thread 1 finished");
        });
        // 線(xiàn)程2:修改共享變量
        Thread thread2 = new Thread(() -> {
            stop = true;
            System.out.println("Thread 2 set stop to true");
        });

        // 啟動(dòng)線(xiàn)程1
        thread1.start();

        // 稍等片刻
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 啟動(dòng)線(xiàn)程2
        thread2.start();
    }
}

? ? ? ?在以上代碼中,兩個(gè)線(xiàn)程分別運(yùn)行,并且共享一個(gè)stop變量。線(xiàn)程1在一個(gè)循環(huán)中檢查stop變量是否為false,而線(xiàn)程2在啟動(dòng)后將stop變量設(shè)置為true。然而,由于沒(méi)有同步機(jī)制,線(xiàn)程1可能不會(huì)立即看到線(xiàn)程2對(duì)stop變量的修改,導(dǎo)致線(xiàn)程1一直在循環(huán)中無(wú)法退出。

private static volatile boolean stop = false;

通過(guò)給stop變量增加volatile修飾,即可保證可見(jiàn)性。

如何保證可見(jiàn)性

? ? ? ?通過(guò)volatile 關(guān)鍵字保證可見(jiàn)性
? ? ? ?通過(guò)內(nèi)存屏障保證可見(jiàn)性
? ? ? ?通過(guò)synchronized 關(guān)鍵字保證可見(jiàn)性
? ? ? ?通過(guò)Lock鎖保證可見(jiàn)性


有序性

? ? ? ?有序性是指程序執(zhí)行的順序按照代碼的先后順序執(zhí)行。在多線(xiàn)程環(huán)境下,由于指令重排序等優(yōu)化,有時(shí)候線(xiàn)程執(zhí)行的順序可能與代碼的順序不一致。

public class ReOrderTest {

    private static  int x = 0, y = 0;
    private  static  int a = 0, b = 0;

    public static void main(String[] args) throws InterruptedException {
        int i=0;
        while (true) {
            i++;
            x = 0;
            y = 0;
            a = 0;
            b = 0;

            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    //用于調(diào)整兩個(gè)線(xiàn)程的執(zhí)行順序
                    shortWait(20000);
                    a = 1; 
                    x = b; 

                }
            });
            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    b = 1;
                    y = a;

                }
            });

            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();

            System.out.println("第" + i + "次(" + x + "," + y + ")");
            if (x==0&&y==0){
                break;
            }
        }
    }
    public static void shortWait(long interval){
        long start = System.nanoTime();
        long end;
        do{
            end = System.nanoTime();
        }while(start + interval >= end);
    }
}

執(zhí)行結(jié)果:x,y出現(xiàn)了0,0的結(jié)果,程序終止。出現(xiàn)這種結(jié)果有可能是重排序?qū)е碌摹?/p>

如何保證有序性

? ? ? ?通過(guò)volatile 關(guān)鍵字保證有序性
? ? ? ?通過(guò)內(nèi)存屏障保證有序性?
? ? ? ?通過(guò)synchronized關(guān)鍵字保證有序性
? ? ? ?通過(guò)Lock鎖保證有序性


Java內(nèi)存模型(JMM內(nèi)存模型)

? ? ? ?Java內(nèi)存模型(Java Memory Model,JMM)是Java程序中多線(xiàn)程并發(fā)訪(fǎng)問(wèn)共享變量時(shí),對(duì)內(nèi)存操作行為的一種規(guī)范。它定義了在多線(xiàn)程環(huán)境中,線(xiàn)程如何與主內(nèi)存和工作內(nèi)存交互,以確保并發(fā)程序的正確性。

? ? ? ? ? ? ??并發(fā)編程之三大特性及JMM內(nèi)存模型,并發(fā)編程,java,開(kāi)發(fā)語(yǔ)言,后端

Java內(nèi)存模型的一些關(guān)鍵概念:

1. 主內(nèi)存(Main Memory): 主內(nèi)存是所有線(xiàn)程共享的內(nèi)存區(qū)域,包含所有的共享變量。所有的線(xiàn)程都可以訪(fǎng)問(wèn)主內(nèi)存。
2. 工作內(nèi)存(Working Memory): 每個(gè)線(xiàn)程有自己的工作內(nèi)存,存儲(chǔ)了該線(xiàn)程使用到的變量的副本。線(xiàn)程對(duì)變量的所有操作都在工作內(nèi)存中進(jìn)行,不直接讀寫(xiě)主內(nèi)存。
3. 共享變量: 多個(gè)線(xiàn)程之間可以共享的變量,例如類(lèi)的靜態(tài)變量或?qū)嵗兞俊?br> 4. 原子性(Atomicity): 單個(gè)的讀/寫(xiě)操作是原子的,即要么完成,要么不開(kāi)始。
5. 可見(jiàn)性(Visibility): 當(dāng)一個(gè)線(xiàn)程修改了共享變量的值,其他線(xiàn)程應(yīng)該能夠立即看到這個(gè)變化。
6. 有序性(Ordering): 程序執(zhí)行的順序與代碼中的順序一致。

主內(nèi)存與工作內(nèi)存交互協(xié)議

從工 作內(nèi)存同步到主內(nèi)存之間的實(shí)現(xiàn)細(xì)節(jié),Java內(nèi)存模型定義了以下八種原子操作來(lái)完成:
lock(鎖定):作用于主內(nèi)存的變量,把一個(gè)變量標(biāo)識(shí)為一條線(xiàn)程獨(dú)占狀態(tài)。
unlock(解鎖):作用于主內(nèi)存變量,把一個(gè)處于鎖定狀態(tài)的變量釋放出來(lái),釋放后的變量才可以被其他線(xiàn)程鎖 定。
read(讀取):作用于主內(nèi)存變量,把一個(gè)變量值從主內(nèi)存?zhèn)鬏數(shù)骄€(xiàn)程的工作內(nèi)存中,以便隨后的load動(dòng)作使用
load(載入):作用于工作內(nèi)存的變量,它把read操作從主內(nèi)存中得到的變量值放入工作內(nèi)存的變量副本中。
use(使用):作用于工作內(nèi)存的變量,把工作內(nèi)存中的一個(gè)變量值傳遞給執(zhí)行引擎,每當(dāng)虛擬機(jī)遇到一個(gè)需要 使用變量的值的字節(jié)碼指令時(shí)將會(huì)執(zhí)行這個(gè)操作。
assign(賦值):作用于工作內(nèi)存的變量,它把一個(gè)從執(zhí)行引擎接收到的值賦值給工作內(nèi)存的變量,每當(dāng)虛擬機(jī) 遇到一個(gè)給變量賦值的字節(jié)碼指令時(shí)執(zhí)行這個(gè)操作。
store(存儲(chǔ)):作用于工作內(nèi)存的變量,把工作內(nèi)存中的一個(gè)變量的值傳送到主內(nèi)存中,以便隨后的write的操 作。
write(寫(xiě)入):作用于主內(nèi)存的變量,它把store操作從工作內(nèi)存中得到的變量的值放入主內(nèi)存的變量中。

并發(fā)編程之三大特性及JMM內(nèi)存模型,并發(fā)編程,java,開(kāi)發(fā)語(yǔ)言,后端

Java內(nèi)存模型通過(guò)以下手段來(lái)確保多線(xiàn)程程序的正確性:

1. 鎖機(jī)制: 使用synchronized關(guān)鍵字或顯式鎖來(lái)保護(hù)共享數(shù)據(jù),確保在同一時(shí)刻只有一個(gè)線(xiàn)程可以訪(fǎng)問(wèn)臨界區(qū)。
2. volatile關(guān)鍵字: 用于修飾共享變量,保證可見(jiàn)性。對(duì)一個(gè)volatile變量的寫(xiě)操作將立即刷新到主內(nèi)存,而讀操作將從主內(nèi)存中加載最新的值。
3. final關(guān)鍵字: 被final修飾的字段在構(gòu)造函數(shù)結(jié)束之前就已經(jīng)對(duì)其他線(xiàn)程可見(jiàn)。
4. Happens-Before關(guān)系: JMM定義了Happens-Before的規(guī)則,確保在某個(gè)操作之前的操作對(duì)其可見(jiàn)。

鎖機(jī)制

1. 當(dāng)線(xiàn)程獲取鎖時(shí),JMM會(huì)把該線(xiàn)程對(duì)應(yīng)的本地內(nèi)存置為無(wú)效。
2. 當(dāng)線(xiàn)程釋放鎖時(shí),JMM會(huì)把該線(xiàn)程對(duì)應(yīng)的本地內(nèi)存中的共享變量刷新到主內(nèi)存中。

? ? ? ?synchronized關(guān)鍵字的作用是確保多個(gè)線(xiàn)程訪(fǎng)問(wèn)共享資源時(shí)的互斥性和可見(jiàn)性。在獲取鎖之前,線(xiàn)程 會(huì)將共享變量的最新值從主內(nèi)存中讀取到線(xiàn)程本地的緩存中,釋放鎖時(shí)會(huì)將修改后的共享變量的值刷 新到主內(nèi)存中,以保證可見(jiàn)性。

volatile

1. 當(dāng)寫(xiě)一個(gè)volatile變量時(shí),JMM會(huì)把該線(xiàn)程對(duì)應(yīng)的本地內(nèi)存中的共享變量值刷新到主內(nèi)存。
2. 當(dāng)讀一個(gè)volatile變量時(shí),JMM會(huì)把該線(xiàn)程對(duì)應(yīng)的本地內(nèi)存置為無(wú)效,線(xiàn)程接下來(lái)將從主內(nèi)存中讀取共享變量。

volatile禁止指令重排序

并發(fā)編程之三大特性及JMM內(nèi)存模型,并發(fā)編程,java,開(kāi)發(fā)語(yǔ)言,后端

?Happens-Before

? ? ? ?Happens-Before是Java內(nèi)存模型(Java Memory Model,JMM)中一個(gè)重要的概念,用于規(guī)定多線(xiàn)程程序中操作之間的執(zhí)行順序和可見(jiàn)性關(guān)系。這個(gè)概念確保了在程序中對(duì)共享變量的操作是按照一定順序執(zhí)行的,以避免出現(xiàn)不確定的結(jié)果和數(shù)據(jù)競(jìng)爭(zhēng)問(wèn)題。

? ? ? ?如果操作A在操作B之前發(fā)生在之前(happens-before),那么操作A對(duì)于操作B來(lái)說(shuō),必定是可見(jiàn)的,而且操作A的效果將被操作B看到。??

Happens-Before部分關(guān)系規(guī)則:

1. 程序順序規(guī)則(Program Order Rule): 在一個(gè)線(xiàn)程中,操作按照程序代碼的先后順序執(zhí)行。
2. 鎖定規(guī)則(Lock Rule): 釋放鎖的操作Happens-Before于后續(xù)對(duì)同一鎖的加鎖操作。
3. volatile變量規(guī)則(Volatile Variable Rule): 對(duì)volatile變量的寫(xiě)操作Happens-Before于后續(xù)對(duì)這個(gè)變量的讀操作。
4. 傳遞性(Transitivity): 如果操作A Happens-Before于操作B,且操作B Happens-Before于操作C,那么操作A Happens-Before于操作C。
5. 線(xiàn)程啟動(dòng)規(guī)則(Thread Start Rule): 線(xiàn)程的啟動(dòng)操作Happens-Before于該線(xiàn)程的任何操作。
6. 線(xiàn)程終止規(guī)則(Thread Termination Rule): 線(xiàn)程的所有操作Happens-Before于其他線(xiàn)程檢測(cè)到該線(xiàn)程已經(jīng)終止。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-805601.html

到了這里,關(guān)于并發(fā)編程之三大特性及JMM內(nèi)存模型的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀(guān)點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • [JVM] 淺談JMM(Java 內(nèi)存模型)

    Java 內(nèi)存模型(Java Memory Model,JMM)是 Java 虛擬機(jī)規(guī)范中定義的一種抽象計(jì)算機(jī)內(nèi)存模型,用于描述 Java 程序在多線(xiàn)程下的內(nèi)存訪(fǎng)問(wèn)行為。JMM 定義了線(xiàn)程之間共享變量的可見(jiàn)性和有序性規(guī)則,為開(kāi)發(fā)者提供了一種可靠的同步機(jī)制,以避免并發(fā)程序中常見(jiàn)的線(xiàn)程安全問(wèn)題。 JMM

    2024年01月16日
    瀏覽(33)
  • Java內(nèi)存區(qū)域(運(yùn)行時(shí)數(shù)據(jù)區(qū)域)和內(nèi)存模型(JMM)

    Java內(nèi)存區(qū)域(運(yùn)行時(shí)數(shù)據(jù)區(qū)域)和內(nèi)存模型(JMM)

    Java?內(nèi)存區(qū)域和內(nèi)存模型是不一樣的東西,內(nèi)存區(qū)域是指 Jvm 運(yùn)行時(shí)將數(shù)據(jù)分區(qū)域存儲(chǔ),強(qiáng)調(diào)對(duì)內(nèi)存空間的劃分。 而內(nèi)存模型(Java Memory?Model,簡(jiǎn)稱(chēng) JMM )是定義了線(xiàn)程和主內(nèi)存之間的抽象關(guān)系,即 JMM 定義了 JVM 在計(jì)算機(jī)內(nèi)存(RAM)中的工作方式,如果我們要想深入了解Java并發(fā)

    2024年02月12日
    瀏覽(32)
  • Java內(nèi)存模型(JMM)和volatile原理

    Java內(nèi)存模型(JMM)和volatile原理

    目錄 一、Java 內(nèi)存模型 二、可見(jiàn)性 三、有序性 四、volatile原理 ?1、可見(jiàn)性保證 2、有序性保證 五、線(xiàn)程安全的單例 JMM即Java Memory Model,他定義了 主存(共享的數(shù)據(jù)) 、 工作內(nèi)存(私有的數(shù)據(jù)) 抽象概念,底層對(duì)應(yīng)著CPU寄存器、緩存、硬件內(nèi)存、CPU指令優(yōu)化等 JMM體現(xiàn)以下

    2024年02月09日
    瀏覽(26)
  • Java 內(nèi)存模型(JMM)探尋原理,深度講解

    Java 內(nèi)存模型(JMM)探尋原理,深度講解

    目錄 一. 前言 二. 為什么會(huì)有內(nèi)存模型 2.1.?硬件內(nèi)存架構(gòu) 2.2.?緩存一致性問(wèn)題 2.3.?處理器優(yōu)化和指令重排序 三.?并發(fā)編程的問(wèn)題 四. Java 內(nèi)存模型(JMM) 4.1.?Java 運(yùn)行時(shí)內(nèi)存區(qū)域與硬件內(nèi)存的關(guān)系 4.2.?Java 線(xiàn)程與主內(nèi)存的關(guān)系 4.3.?線(xiàn)程間通信 五. 主內(nèi)存和工作內(nèi)存 六.?J

    2024年04月22日
    瀏覽(27)
  • 【Java多線(xiàn)程學(xué)習(xí)7】JMM(Java內(nèi)存模型)學(xué)習(xí)

    【Java多線(xiàn)程學(xué)習(xí)7】JMM(Java內(nèi)存模型)學(xué)習(xí)

    JMM(Java內(nèi)存模型),可以看作是 Java定義的并發(fā)編程相關(guān)的一組規(guī)范 ,除了抽象了 線(xiàn)程和主內(nèi)存 之間的關(guān)系之外,其還規(guī)定了從 Java源代碼 到 CPU可執(zhí)行指令 的這個(gè)轉(zhuǎn)化過(guò)程中要遵守哪些并發(fā)相關(guān)的原則和規(guī)范,其主要目的是 簡(jiǎn)化多線(xiàn)程編程 , 增強(qiáng)程序的可移植性 。 至于

    2024年02月11日
    瀏覽(25)
  • java八股文面試[多線(xiàn)程]——并發(fā)三大特性 原子 可見(jiàn) 順序

    java八股文面試[多線(xiàn)程]——并發(fā)三大特性 原子 可見(jiàn) 順序

    ? ? AutomicInteger :? volatile + CAS 總線(xiàn)LOCK? MESI 兩個(gè)協(xié)議 TODO volatile的可見(jiàn)性和禁止重排序是怎么實(shí)現(xiàn)的: DCL場(chǎng)景:? new操作會(huì)在字節(jié)碼層面生成兩個(gè)步驟: 分配內(nèi)存、調(diào)用構(gòu)造器 然后把引用賦值給singleton 不加volatile則會(huì)發(fā)生指令重排,可能得到不完整的對(duì)象 知識(shí)來(lái)源: 【并

    2024年02月11日
    瀏覽(25)
  • 區(qū)分什么是Java內(nèi)存模型(JMM)和 JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)

    區(qū)分什么是Java內(nèi)存模型(JMM)和 JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)

    Java的內(nèi)存區(qū)域和內(nèi)存模型是不一樣的東西,內(nèi)存區(qū)域是指 JVM 運(yùn)行時(shí)將數(shù)據(jù)分區(qū)域存儲(chǔ),強(qiáng)調(diào)對(duì)內(nèi)存空間的劃分 。 而內(nèi)存模型(Java Memory Model,簡(jiǎn)稱(chēng) JMM )是 定義了線(xiàn)程和主內(nèi)存之間的抽象關(guān)系,即 JMM 定義了 JVM 在計(jì)算機(jī)內(nèi)存(RAM)中的工作方式 ,如果我們要想深入了解Java并

    2024年02月11日
    瀏覽(31)
  • 并發(fā)編程_jmm部分

    并發(fā)編程_jmm部分

    前提:并發(fā)編程有3大問(wèn)題,可見(jiàn)性、有序性、原子性。 導(dǎo)致 可見(jiàn)性 的原因是緩存, 有序性 的原因是 編譯器優(yōu)化。解決方法就是直接禁用緩存和編譯器優(yōu)化,導(dǎo)致程序性能堪憂(yōu)。 因此合理的方案就是 按需 禁用緩存和編譯器優(yōu)化。 JMM定義了線(xiàn)程和主內(nèi)存之間的抽象關(guān)系:

    2024年02月13日
    瀏覽(27)
  • 【javaEE面試題(五)在JMM(Java Memory Model (Java 內(nèi)存模型))下談volatile的作用】

    【javaEE面試題(五)在JMM(Java Memory Model (Java 內(nèi)存模型))下談volatile的作用】

    volatile 能保證內(nèi)存可見(jiàn)性 volatile 修飾的變量, 能夠保證 “內(nèi)存可見(jiàn)性”. 代碼在寫(xiě)入 volatile 修飾的變量的時(shí)候 改變線(xiàn)程工作內(nèi)存中volatile變量副本的值 將改變后的副本的值從工作內(nèi)存 刷新到主內(nèi)存 代碼在讀取 volatile 修飾的變量的時(shí)候 從主內(nèi)存中讀取volatile變量的最新值到

    2024年02月13日
    瀏覽(22)
  • 【javaEE面試題(五)在JMM(Java Memory Model (Java 內(nèi)存模型))下談volatile的作用】【保證內(nèi)存可見(jiàn) 和 指令有序】

    【javaEE面試題(五)在JMM(Java Memory Model (Java 內(nèi)存模型))下談volatile的作用】【保證內(nèi)存可見(jiàn) 和 指令有序】

    volatile 能保證內(nèi)存可見(jiàn)性 volatile 修飾的變量, 能夠保證 “內(nèi)存可見(jiàn)性”. 代碼在寫(xiě)入 volatile 修飾的變量的時(shí)候 改變線(xiàn)程工作內(nèi)存中volatile變量副本的值 將改變后的副本的值從工作內(nèi)存 刷新到主內(nèi)存 代碼在讀取 volatile 修飾的變量的時(shí)候 從主內(nèi)存中讀取volatile變量的最新值到

    2024年02月16日
    瀏覽(33)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包