在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Java運(yùn)行時(shí)內(nèi)存區(qū)域與硬件內(nèi)存的關(guān)系2

jf_78858299 ? 來源:小牛呼嚕嚕 ? 作者:小牛呼嚕嚕 ? 2023-02-09 14:41 ? 次閱讀

線程間通信

線程間的通信一般有兩種方式進(jìn)行,一是通過消息傳遞,二是共享內(nèi)存Java 線程間的通信采用的是共享內(nèi)存方式,JMM 為共享變量提供了線程間的保障。如果兩個(gè)線程都對(duì)一個(gè)共享變量進(jìn)行操作,共享變量初始值為 1,每個(gè)線程都變量進(jìn)行加 1,預(yù)期共享變量的值為 3。在 JMM 規(guī)范下會(huì)有一系列的操作。我們直接來看下圖:

在多線程的情況下,對(duì)主內(nèi)存中的共享變量進(jìn)行操作可能發(fā)生線程安全問題,比如:線程 1 和線程 2 同時(shí)對(duì)同一個(gè)共享變量進(jìn)行操作,執(zhí)行+1操作,線程 1 、線程2 讀取的共享變量是否是彼此修改前還是修改后的值呢,這個(gè)是無法確定的,這種情況和CPU的高速緩存與內(nèi)存之間的問題非常相似

如何實(shí)現(xiàn)主內(nèi)存與工作內(nèi)存的變量同步,為了更好的控制主內(nèi)存和本地內(nèi)存的交互,Java 內(nèi)存模型定義了八種操作來實(shí)現(xiàn):

  • lock:鎖定。作用于主內(nèi)存的變量,把一個(gè)變量標(biāo)識(shí)為一條線程獨(dú)占狀態(tài)。
  • unlock:解鎖。作用于主內(nèi)存變量,把一個(gè)處于鎖定狀態(tài)的變量釋放出來,釋放后的變量才可以被其他線程鎖定。
  • read:讀取。作用于主內(nèi)存變量,把一個(gè)變量值從主內(nèi)存?zhèn)鬏數(shù)骄€程的工作內(nèi)存中,以便隨后的load動(dòng)作使用
  • load:載入。作用于工作內(nèi)存的變量,它把read操作從主內(nèi)存中得到的變量值放入工作內(nèi)存的變量副本中。工作內(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:寫入。作用于主內(nèi)存的變量,它把store操作從工作內(nèi)存中一個(gè)變量的值傳送到主內(nèi)存的變量中。

重溫Java 并發(fā)三大特性

原子性

原子性:即一個(gè)或者多個(gè)操作作為一個(gè)整體,要么全部執(zhí)行,要么都不執(zhí)行,并且操作在執(zhí)行過程中不會(huì)被線程調(diào)度機(jī)制打斷;而且這種操作一旦開始,就一直運(yùn)行到結(jié)束,中間不會(huì)有任何上下文切換(context switch) 比如:

int i = 0;   //語句1,原子性

i++;         //語句2,非原子性

語句1大家一幕了然,語句2卻許多人容易犯迷糊,i++ 其實(shí)可以分為3步:

  1. i 被從局部變量表(內(nèi)存)取出,
  2. 壓入操作棧(寄存器),操作棧中自增
  3. 使用棧頂值更新局部變量表(寄存器更新寫入內(nèi)存)

執(zhí)行上述3個(gè)步驟的時(shí)候是可以進(jìn)行線程切換的,或者說是可以被另其他線程的 這3 步打斷的,因此語句2不是一個(gè)原子性操作

在 Java 中,可以借助synchronized 、各種 Lock 以及各種原子類實(shí)現(xiàn)原子性。synchronized 和各種Lock是通過保證任一時(shí)刻只有一個(gè)線程訪問該代碼塊,因此可以保證其原子性。各種原子類是利用CAS (compare and swap)操作(可能也會(huì)用到 volatile或者final關(guān)鍵字)來保證原子操作。

可見性

可見性是指當(dāng)多個(gè)線程訪問同一個(gè)變量時(shí),一個(gè)線程修改了這個(gè)變量的值,其他線程能夠立即看到修改的值。我們來看一個(gè)例子:

public class VisibilityTest {
    private boolean flag = true;

    public void change() {
        flag = false;
        System.out.println(Thread.currentThread().getName() + ",已修改flag=false");
    }

    public void load() {
        System.out.println(Thread.currentThread().getName() + ",開始執(zhí)行.....");
        int i = 0;
        while (flag) {
            i++;
        }
        System.out.println(Thread.currentThread().getName() + ",結(jié)束循環(huán)");
    }

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

        // 線程threadA模擬數(shù)據(jù)加載場(chǎng)景
        Thread threadA = new Thread(() -> test.load(), "threadA");
        threadA.start();

        // 讓threadA執(zhí)行一會(huì)兒
        Thread.sleep(1000);
        // 線程threadB 修改 共享變量flag
        Thread threadB = new Thread(() -> test.change(), "threadB");
        threadB.start();

    }
}

threadA 負(fù)責(zé)循環(huán),threadB負(fù)責(zé)修改 共享變量flag,如果flag=false時(shí),threadA 會(huì)結(jié)束循環(huán),但是上面的例子會(huì)死循環(huán)。原因是threadA無法立即讀取到共享變量flag修改后的值。我們只需 private volatile boolean flag = true;加上volatile關(guān)鍵字threadA就可以立即退出循環(huán)了。

Java中的volatile關(guān)鍵字提供了一個(gè)功能,那就是被其修飾的變量在被修改后可以立即同步到主內(nèi)存,被其修飾的變量在每次是用之前都從主內(nèi)存刷新。

因此,可以使用volatile來保證多線程操作時(shí)變量的可見性。除了volatile,Java中的synchronizedfinal兩個(gè)關(guān)鍵字 以及各種 Lock也可以實(shí)現(xiàn)可見性。

有序性

有序性:即程序執(zhí)行的順序按照代碼的先后順序執(zhí)行。

int i = 0;
int j = 0;
i = 10;   //語句1
j = 1;    //語句2

但由于指令重排序問題,代碼的執(zhí)行順序未必就是編寫代碼時(shí)候的順序。語句可能的執(zhí)行順序如下:

  1. 語句1 語句2
  2. 語句2 語句1

指令重排對(duì)于非原子性的操作,在不影響最終結(jié)果的情況下,其拆分成的原子操作可能會(huì)被重新排列執(zhí)行順序。 指令重排不會(huì)影響單線程的執(zhí)行結(jié)果,但是會(huì)影響多線程并發(fā)執(zhí)行的結(jié)果正確性 。在Java 中,可以通過volatile關(guān)鍵字來禁止指令進(jìn)行重排序優(yōu)化,詳情可見:https://mp.weixin.qq.com/s/TyiCfVMeeDwa-2hd9N9XJQ。也可以使用synchronized關(guān)鍵字保證同一時(shí)刻只允許一條線程訪問程序塊。


參考資料:

《java并發(fā)編程實(shí)戰(zhàn)》

https://www.cnblogs.com/czwbig/p/11127124.html

https://www.cnblogs.com/jelly12345/p/14609657.html

https://www.cnblogs.com/bailiyi/p/11967396.html

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • JAVA
    +關(guān)注

    關(guān)注

    20

    文章

    2987

    瀏覽量

    107174
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1657

    瀏覽量

    49945
  • JVM
    JVM
    +關(guān)注

    關(guān)注

    0

    文章

    160

    瀏覽量

    12538
收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    Labview 運(yùn)行時(shí)內(nèi)存增加

    的dll,用庫函數(shù)直接調(diào)用這個(gè)dll后,Labview運(yùn)行時(shí)所占的內(nèi)存基本上保持在0.9 M左右,不會(huì)卡死了。附件里是那個(gè)網(wǎng)友上傳的dll,大家可以下載后將.jpg改為.dll
    發(fā)表于 05-19 14:38

    C6748內(nèi)存分配運(yùn)行時(shí)出錯(cuò)

    因?yàn)樾枰獙?duì)大量數(shù)據(jù)進(jìn)行處理,我設(shè)置一個(gè)指針,內(nèi)存分配1000*sizeof(float),運(yùn)行時(shí)出錯(cuò),查看其地址為0x00000000(肯定不對(duì)),如果減小分配空間,如200*sizeof
    發(fā)表于 03-16 10:05

    C語言內(nèi)存運(yùn)行時(shí)不同變量是怎樣分配的

    C語言內(nèi)存運(yùn)行時(shí)不同變量是怎樣分配的?怎樣驗(yàn)證C語言編譯后的內(nèi)存地址分配是否合理?
    發(fā)表于 02-25 06:37

    請(qǐng)問單片機(jī)運(yùn)行時(shí)內(nèi)存是如何分配的?

    請(qǐng)問單片機(jī)運(yùn)行時(shí)內(nèi)存是如何分配的? 是在鏈接腳本中人工定義?還是編譯器根據(jù)某種算法自動(dòng)分配?
    發(fā)表于 09-27 08:16

    java線程內(nèi)存模型

    一、Java內(nèi)存模型 按照官方的說法:Java 虛擬機(jī)具有一個(gè)堆,堆是運(yùn)行時(shí)數(shù)據(jù)區(qū)域,所有類實(shí)例和數(shù)組的
    發(fā)表于 09-27 10:55 ?0次下載
    <b class='flag-5'>java</b>線程<b class='flag-5'>內(nèi)存</b>模型

    Java內(nèi)存模型及原理分析

    一、Java內(nèi)存模型 按照官方的說法:Java 虛擬機(jī)具有一個(gè)堆,堆是運(yùn)行時(shí)數(shù)據(jù)區(qū)域,所有類實(shí)例和數(shù)組的
    發(fā)表于 09-28 11:49 ?0次下載
    <b class='flag-5'>Java</b><b class='flag-5'>內(nèi)存</b>模型及原理分析

    利用StopWatch監(jiān)控Java代碼運(yùn)行時(shí)間和分析性能

    利用StopWatch監(jiān)控Java代碼運(yùn)行時(shí)間和分析性能。
    的頭像 發(fā)表于 07-21 16:51 ?3150次閱讀

    Java運(yùn)行時(shí)內(nèi)存區(qū)域硬件內(nèi)存關(guān)系1

    在上一篇文章中,我們了解了計(jì)算機(jī)由于各個(gè)硬件的讀取速度之間的巨大差距,和充分利用CPU的性能的手段方法,及其所帶來的一系列問題: 1. 為了充分壓榨CPU的性能, **CPU 會(huì)對(duì)指令亂序執(zhí)行或者語言的編譯器會(huì)指令重排** ,讓CPU一直工作不停歇,但同時(shí)會(huì)導(dǎo)致`有序性問題`。
    的頭像 發(fā)表于 02-09 14:41 ?500次閱讀

    JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)之堆內(nèi)存

    說一下 JVM 運(yùn)行時(shí)數(shù)據(jù)區(qū)吧,都有哪些區(qū)?分別是干什么的?
    的頭像 發(fā)表于 08-19 14:35 ?923次閱讀
    JVM<b class='flag-5'>運(yùn)行時(shí)</b>數(shù)據(jù)區(qū)之堆<b class='flag-5'>內(nèi)存</b>

    如何查看java程序的內(nèi)存分布

    要查看Java程序的內(nèi)存分布,首先需要了解Java程序運(yùn)行時(shí)內(nèi)存模型。 Java程序的
    的頭像 發(fā)表于 11-23 14:47 ?1304次閱讀

    jvm內(nèi)存模型和內(nèi)存結(jié)構(gòu)

    內(nèi)存模型是指Java程序在運(yùn)行時(shí),JVM對(duì)內(nèi)存空間的組織和管理方式。它包括了線程私有的部分和線程共享的部分。 線程私有部分 線程私有部分主要包含了棧(Stack)和程序計(jì)數(shù)器(Prog
    的頭像 發(fā)表于 12-05 11:08 ?1193次閱讀

    jvm運(yùn)行時(shí)內(nèi)存區(qū)域劃分

    內(nèi)存區(qū)域劃分對(duì)于了解Java程序的內(nèi)存使用非常重要,本文將詳細(xì)介紹JVM運(yùn)行時(shí)內(nèi)存
    的頭像 發(fā)表于 12-05 14:08 ?705次閱讀

    jvm管理的內(nèi)存包括哪幾個(gè)運(yùn)行時(shí)數(shù)據(jù)內(nèi)存

    JVM(Java虛擬機(jī))是Java程序的運(yùn)行環(huán)境,它提供了內(nèi)存管理機(jī)制來管理Java程序所需的運(yùn)行時(shí)
    的頭像 發(fā)表于 12-05 14:09 ?792次閱讀

    jvm內(nèi)存區(qū)域中,哪一塊是屬于線程共享

    是如何劃分的。JVM內(nèi)存區(qū)域主要分為以下幾個(gè)部分:程序計(jì)數(shù)器、Java虛擬機(jī)棧、本地方法棧、堆、方法區(qū)和運(yùn)行時(shí)常量池。其中,程序計(jì)數(shù)器、Java
    的頭像 發(fā)表于 12-05 14:14 ?1669次閱讀

    java虛擬機(jī)內(nèi)存包括遠(yuǎn)空間內(nèi)存

    Java虛擬機(jī)(JVM)內(nèi)存Java程序執(zhí)行時(shí)所使用的內(nèi)存空間的總稱,包括了Java堆、方法區(qū)
    的頭像 發(fā)表于 12-05 14:15 ?572次閱讀
    主站蜘蛛池模板: 欧美aaaav免费大片 | 在线视频图片小说 | 丝袜紧身裙国产在线播放 | 一级特黄国产高清毛片97看片 | 欧美网站免费 | 爱看精品福利视频观看 | 国产免费久久精品 | 又黄又爽又猛大片录像 | 免费的黄视频 | 美女免费视频色在线观看 | 免费拍拍视频 | 国产免费黄视频 | 五月婷婷伊人网 | aaaa日本| 欧美一卡二卡科技有限公司 | 中文字幕一区二区三区精品 | 亚洲欧美圣爱天天综合 | 免费看啪| 视频一区日韩 | 四虎影院永久在线 | 午夜三级网站 | 日本久草网 | 色香蕉在线 | 日韩高清特级特黄毛片 | 日本黄色片在线播放 | 一级毛片无毒不卡直接观看 | 一级a毛片免费观看 | 天天干影视| 精品成人毛片一区二区视 | 天天爽夜夜爽人人爽一区二区 | 亚欧洲乱码专区视频 | 国产一级大片免费看 | 欧美色图日韩色图 | 日本在线观看永久免费网站 | 国产亚洲精品久久yy5099 | 国产欧美视频在线 | 91大神大战高跟丝袜美女 | 性xxxxbbbb免费播放视频 | 亚洲天堂免费 | 四虎网址 | 久久精品国产精品亚洲红杏 |