真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

實(shí)例分析JMM和Volatile的底層原理-創(chuàng)新互聯(lián)

本篇內(nèi)容主要講解“實(shí)例分析JMM和Volatile的底層原理”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“實(shí)例分析JMM和Volatile的底層原理”吧!

為洮北等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及洮北網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都網(wǎng)站制作、成都做網(wǎng)站、洮北網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!

JMM和volatile分析

1.JMM:Java Memory Model,java線程內(nèi)存模型

JMM:它是一個(gè)抽象的概念,描述的是線程和內(nèi)存間的通信,java線程內(nèi)存模型和CPU緩存模型類似,它是標(biāo)準(zhǔn)化的,用于屏蔽硬件和操作系統(tǒng)對(duì)內(nèi)存訪問(wèn)的差異性。

2.JMM和8大原子操作結(jié)合

3.volatile的應(yīng)用及底層原理探究

volatile : 輕量級(jí)的synchronized,在多處理器的開(kāi)發(fā)中保證了共享變量的"可見(jiàn)性"??梢?jiàn)性的意思:當(dāng)一個(gè)線程修改了某個(gè)共享變量時(shí),其他使用到該共享變量的線程能夠及時(shí)讀取到修改的值。修飾得當(dāng),比synchronized的執(zhí)行成本更低,因?yàn)樗粫?huì)引起線程上下文切換和調(diào)度。

public class VolatileTest {  private static volatile boolean flag = false;  public static void main(String[] args) {    update();  }  public static void update(){    flag = true;    System.out.println(flag);  }}Volatile JIT編譯器編譯java代碼為匯編指令查看1.在jdk\jre\bin\ 目錄下添加 hsdis-amd64.lib2.在jdk1.8\jre\bin\server\目錄下添加hsdis-amd64.dll文件3.在IDEA中設(shè)置 JVM參數(shù)-server -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=compileonly,VolatileTest.update4.運(yùn)行Java程序即可打印出CompilerOracle: compileonly *VolatileTest.updateLoaded disassembler from E:\EclipseDev\jdk\jdk1.8\jre\bin\server\hsdis-amd64.dllDecoding compiled method 0x000000000f11aad0:Code:Argument 0 is unknown.RIP: 0xf11ac40 Code size: 0x000002a8[Disassembling for mach='amd64'][Entry Point][Verified Entry Point][Constants] # {method} {0x0000000008792b78} 'update' '()V' in 'com/yew/test/VolatileTest' #      [sp+0x40] (sp of caller) 0x000000000f11ac40: mov   dword ptr [rsp+0ffffffffffffa000h],eax 0x000000000f11ac47: push  rbp 0x000000000f11ac48: sub   rsp,30h 0x000000000f11ac4c: mov   r8,8792d70h    ;  {metadata(method data for {method} {0x0000000008792b78} 'update' '()V' in 'com/yew/test/VolatileTest')} 0x000000000f11ac56: mov   edx,dword ptr [r8+0dch] 0x000000000f11ac5d: add   edx,8h 0x000000000f11ac60: mov   dword ptr [r8+0dch],edx 0x000000000f11ac67: mov   r8,8792b70h    ;  {metadata({method} {0x0000000008792b78} 'update' '()V' in 'com/yew/test/VolatileTest')} 0x000000000f11ac71: and   edx,0h 0x000000000f11ac74: cmp   edx,0h 0x000000000f11ac77: je   0f11ad68h     ;*iconst_1                        ; - com.yew.test.VolatileTest::update@0 (line 17) 0x000000000f11ac7d: mov   r8,0d7b08a30h   ;  {oop(a 'java/lang/Class' = 'com/yew/test/VolatileTest')} 0x000000000f11ac87: mov   edx,1h 0x000000000f11ac8c: mov   byte ptr [r8+68h],dlvolatile修飾 0x000000000f11ac90: lock add dword ptr [rsp],0h ;*putstatic flag                        ; - com.yew.test.VolatileTest::update@1 (line 17)無(wú)Volatile修飾 0x000000000f113707: mov byte ptr [r8+68h],1h ;*putstatic flag                        ; - com.yew.test.VolatileTest::update@1 (line 17)通過(guò)比較可知:改變共享變量flag的值為true,該變量由Volatile修飾,進(jìn)行匯編打印時(shí),會(huì)有l(wèi)ock前綴修飾,根據(jù)IA-32架構(gòu)軟件開(kāi)發(fā)者手冊(cè)可知,lock前綴指令在多核CPU處理器下會(huì)引發(fā)兩件事情:【1】將當(dāng)前處理器緩存行的數(shù)據(jù)立即寫(xiě)回系統(tǒng)內(nèi)存【2】wirte操作會(huì)使其他處理器中緩存該內(nèi)存地址的數(shù)據(jù)無(wú)效LOCK#聲言期間,處理器獨(dú)占任何共享內(nèi)存。IA-32處理器和Intel 64處理器使用MESI(修改、獨(dú)占、共享、無(wú)效)控制協(xié)議去維護(hù)內(nèi)部緩存和其他處理器緩存的一致性。通過(guò)嗅探技術(shù)保證處理器內(nèi)部緩存、系統(tǒng)緩存和其他處理器緩存的數(shù)據(jù)再總線上保持一致。當(dāng)其他處理器打算回寫(xiě)內(nèi)存地址,該地址是共享內(nèi)存區(qū)域,那么嗅探的處理器會(huì)將它的緩存行設(shè)置為無(wú)效,下次訪問(wèn)相同內(nèi)存時(shí),強(qiáng)制執(zhí)行緩存行填充。0x000000000f11ac95: nop 0x000000000f11ac98: jmp   0f11add4h     ;  {no_reloc} 0x000000000f11ac9d: add   byte ptr [rax],al 0x000000000f11ac9f: add   byte ptr [rax],al 0x000000000f11aca1: add   byte ptr [rsi+0fh],ah 0x000000000f11aca4: Fatal error: Disassembling failed with error code: 15Decoding compiled method 0x000000000f11ef50:Code:Argument 0 is unknown.RIP: 0xf11f080 Code size: 0x00000058[Entry Point][Verified Entry Point][Constants] # {method} {0x0000000008792b78} 'update' '()V' in 'com/yew/test/VolatileTest' #      [sp+0x20] (sp of caller) 0x000000000f11f080: mov   dword ptr [rsp+0ffffffffffffa000h],eax 0x000000000f11f087: push  rbp 0x000000000f11f088: sub   rsp,10h 0x000000000f11f08c: mov   r10,0d7b08a30h  ;  {oop(a 'java/lang/Class' = 'com/yew/test/VolatileTest')} 0x000000000f11f096: mov   byte ptr [r10+68h],1h 0x000000000f11f09b: lock add dword ptr [rsp],0h ;*putstatic flag                        ; - com.yew.test.VolatileTest::update@1 (line 17) 0x000000000f11f0a0: mov   edx,1ch 0x000000000f11f0a5: nop 0x000000000f11f0a7: call  0f0557a0h     ; OopMap{off=44}                        ;*getstatic out                        ; - com.yew.test.VolatileTest::update@4 (line 18)                        ;  {runtime_call} 0x000000000f11f0ac: int3           ;*getstatic out                        ; - com.yew.test.VolatileTest::update@4 (line 18) 0x000000000f11f0ad: hlt 0x000000000f11f0ae: hlt 0x000000000f11f0af: hlt 0x000000000f11f0b0: hlt 0x000000000f11f0b1: hlt 0x000000000f11f0b2: hlt 0x000000000f11f0b3: hlt 0x000000000f11f0b4: hlt 0x000000000f11f0b5: hlt 0x000000000f11f0b6: hlt 0x000000000f11f0b7: hlt 0x000000000f11f0b8: hlt 0x000000000f11f0b9: hlt 0x000000000f11f0ba: hlt 0x000000000f11f0bb: hlt 0x000000000f11f0bc: hlt 0x000000000f11f0bd: hlt 0x000000000f11f0be: hlt 0x000000000f11f0bf: hlt[Exception Handler][Stub Code] 0x000000000f11f0c0: jmp   0f0883a0h     ;  {no_reloc}[Deopt Handler Code] 0x000000000f11f0c5: call  0f11f0cah 0x000000000f11f0ca: sub   qword ptr [rsp],5h 0x000000000f11f0cf: jmp   0f057600h     ;  {runtime_call} 0x000000000f11f0d4: hlt 0x000000000f11f0d5: hlt 0x000000000f11f0d6: hlt 0x000000000f11f0d7: hlttrue

4.volatile的使用優(yōu)化

java并發(fā)大師Doug Li在jdk7并發(fā)包中新增了一個(gè)隊(duì)列集合LinkeTransferQueue,它在使用Volatile關(guān)鍵字修飾變量時(shí),采用追加字節(jié)的方式將變量填充到64字節(jié)

volatile修飾變量在進(jìn)行修改時(shí),會(huì)進(jìn)行LOCK前置指令加鎖,鎖住緩存行的數(shù)據(jù)獨(dú)占

適用于:緩存行字節(jié)為64字節(jié) 處理器如 I7 酷睿 Pentium M等

不適用:非64字節(jié)寬的緩存行 P6系列或者奔騰 共享變量不會(huì)被頻繁的寫(xiě)

5.并發(fā)編程的三大特性:可見(jiàn)性、原子性、有序性

volatile可以保證可見(jiàn)性、有序性,但是不保證原子性。

6.volatile關(guān)鍵字的語(yǔ)義分析

(1)保證可見(jiàn)性,volatile修飾的共享變量被修改時(shí),其他處理器能立刻嗅探到共享變量值的改變

(2)保證有序性:根據(jù)happens-before原則可知,當(dāng)變量使用volatile修飾時(shí),程序代碼前后的位置不能發(fā)生指令重排和提取。

(3)volatile底層采用匯編的lock前綴指令鎖定共享變量?jī)?nèi)存地址的緩存行,從而控制并發(fā)的安全性(輕量級(jí)synchronized)

7.volatile使用場(chǎng)景以及和synchronized的區(qū)別

使用場(chǎng)景:1.標(biāo)志狀態(tài) 2.DCL--雙重檢測(cè)鎖(單例模式) 3.保證可見(jiàn)性、順序性

區(qū)別:

1.使用上:volatile修飾變量 synchronized修飾方法或者代碼塊

2.原子性的保證 volatile不保證原子性 synchronized可以保證原子性

3.可見(jiàn)性保證機(jī)制不同 volatile通過(guò)匯編的lock前綴指令 synchronized使用Monitor屬性(Moniterentet 入口 Moniterexit--出口(包含異常))

4.有序性保證的鎖的粒度 volatile粒度小,synchronized粒度大

5.其他 volatile不會(huì)引起線程阻塞 synchronized會(huì)引起線程的阻塞

到此,相信大家對(duì)“實(shí)例分析JMM和Volatile的底層原理”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)建站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!


分享標(biāo)題:實(shí)例分析JMM和Volatile的底層原理-創(chuàng)新互聯(lián)
轉(zhuǎn)載來(lái)于:http://weahome.cn/article/pjijs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部