成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:有了解過指令重排嗎,什么是Happens-Before

開發(fā) 后端
指令重排可以保證串行語義一致,但是沒有義務(wù)保證多線程間的語義也一致**。所以在多線程下,指令重排序可能會導(dǎo)致一些問題。


重排序

首先,什么是重排序?計算機在執(zhí)行過程中,為了提高性能,會對編譯器和編譯器做指令重排。

這么做為啥可以提高性能呢?

我們知道計算機在執(zhí)行的時候都是一個個指令去執(zhí)行,不同的指令可能操作的硬件不一樣,在執(zhí)行的過程中可能會產(chǎn)生中斷,打個比方,兩個指令a和b他們操作的東西各不相同,如果加載a的時候停頓了,b就加載不到,但是實際上它們互補影響,我也可以先加載b在加載a,所以指令重排是減少停頓的一種方法,這樣大大提高了效率。

指令重排的方式

指令重排一般分為以下三種:

  • 編譯器優(yōu)化重新安排語句的執(zhí)行順序。
  • 指令并行重排利用指令級并行技術(shù)將多個指令并行執(zhí)行,如果指令之前沒有數(shù)據(jù)依賴,處理器可以改變對應(yīng)機器指令的執(zhí)行順序。
  • 內(nèi)存系統(tǒng)重排由于處理使用緩存和讀寫緩沖區(qū),所以它們是亂序的。

指令重排可以保證串行語義一致,但是沒有義務(wù)保證多線程間的語義也一致**。所以在多線程下,指令重排序可能會導(dǎo)致一些問題。

順序一致性模型

順序一致性模型是一個「理論參考模型」,內(nèi)存模型在設(shè)計的時候都會以順序一致性內(nèi)存模型作為參考。

數(shù)據(jù)競爭

我們知道在多線程情況下,同時讀寫一個變量會導(dǎo)致結(jié)果的不確定性,這就存在了數(shù)據(jù)競爭,相反的如果線程在同步情況下,就不存在數(shù)據(jù)競爭。

JMM對于同步的多線程情況下,程序執(zhí)行可以保證順序一致性,同步包括了使用volatile、final、synchronized等關(guān)鍵字來實現(xiàn)「多線程下的同步」,這里的前提正確使用它們,如果使用不當(dāng),就不能保證

什么是順序一致性模型

我們在上節(jié)給大家講了Java的內(nèi)存模型,提到了內(nèi)存可見性的概念,順序一致性模型它的最終目的就是保證內(nèi)存的可見性。

它主要有兩大特性:

  • 一個線程中的所有操作必須按照程序的順序(代碼順序)來執(zhí)行。
  • 不管線程是否同步,所有線程保持單一的執(zhí)行順序并且可見,且是原子性

JMM中同步的順序一致性

在JMM中,臨界區(qū)(同步方法或同步塊)的代碼可以發(fā)生重排,但對其它線程是無感知的,這樣既提高了執(zhí)行效率又不影響最終結(jié)果

JMM中未同步的順序一致性

  • JMM沒有保證未同步程序的執(zhí)行結(jié)果與該程序在順序一致性中執(zhí)行結(jié)果一致。
  • JMM不保證單線程內(nèi)的操作會按程序的順序執(zhí)行(因為指令重排)。
  • JMM不保證所有線程能看到一致的操作執(zhí)行順序(因為不能保證所以操作立即可見)。
  • JMM不保證對64位的long型和double型變量的寫操作具有原子性。

什么是happens-before

JMM提供了「happens-before規(guī)則」(JSR-133規(guī)范), 開發(fā)者可以遵循這種規(guī)范編寫程序,可以保證程序在JMM中具有強的內(nèi)存可見性。JMM使用happens-before的概念來定制兩個操作之間的執(zhí)行順序。這兩個操作可以在一個線程以內(nèi),也可以是不同的線程之間。因此,JMM可以通過happens-before關(guān)系向程序員提供跨線程的內(nèi)存可見性保證。

happens-before關(guān)系的定義如下:

  1. 如果一個操作happens-before另一個操作,那么第一個操作的執(zhí)行結(jié)果將對第二個操作可見,而且第一個操作的執(zhí)行順序排在第二個操作之前。
  2. 「兩個操作之間存在happens-before關(guān)系,并不意味著Java平臺的具體實現(xiàn)必須要按照happens-before關(guān)系指定的順序來執(zhí)行。如果重排序之后的執(zhí)行結(jié)果,與按happens-before關(guān)系來執(zhí)行的結(jié)果一致,那么JMM也允許這樣的重排序。」

總之,「如果操作A happens-before操作B,那么操作A在內(nèi)存上所做的操作對操作B都是可見的,不管它們在不在一個線程。」

在Java中,有以下天然的happens-before關(guān)系:

  • 程序順序規(guī)則:一個線程中的每一個操作,happens-before于該線程中的任意后續(xù)操作。
  • 監(jiān)視器鎖規(guī)則:對一個鎖的解鎖,happens-before于隨后對這個鎖的加鎖。
  • volatile變量規(guī)則:對一個volatile域的寫,happens-before于任意后續(xù)對這個volatile域的讀。
  • 傳遞性:如果A happens-before B,且B happens-before C,那么A happens-before C。
  • start規(guī)則:ThreadA start happens-before ThreadB start
  • join規(guī)則:如果線程A執(zhí)行操作ThreadB.join()并成功返回,那么線程B中的任意操作happens-before于線程A從ThreadB.join()操作成功返回。

結(jié)束語

本節(jié)內(nèi)容可能不像之前那么好理解,比較抽象,所以本文也有不足的地方,大家自己可以多查查一些資料,綜合理解。下一節(jié),帶大家深入學(xué)習(xí)一下Java的volatile。

責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2020-05-28 07:50:18

重排序happens-befCPU

2022-07-26 08:40:42

Java并發(fā)工具類

2022-08-02 06:31:32

Java并發(fā)工具類

2022-07-11 10:47:46

容器JAVA

2022-06-10 13:56:42

Java

2022-06-30 08:14:05

Java阻塞隊列

2022-06-27 08:01:45

Java內(nèi)存模型

2022-06-24 06:43:57

線程池線程復(fù)用

2022-06-15 15:14:17

Java公平鎖非公平鎖

2022-06-09 11:20:44

volatile關(guān)鍵字

2022-06-30 14:31:57

Java阻塞隊列

2024-09-09 08:30:56

代碼

2021-05-09 18:32:05

JMMHappens-befJava

2022-07-18 14:18:26

Babel代碼面試

2021-09-07 10:44:33

Java 注解開發(fā)

2021-04-12 21:34:29

Redis故障數(shù)據(jù)

2024-02-22 15:36:23

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

2021-12-08 06:53:29

面試動態(tài)代理

2022-09-29 07:30:57

數(shù)據(jù)庫索引字段

2022-08-17 07:53:10

Volatile關(guān)鍵字原子性
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 国产一区二区三区在线看 | 午夜影院在线观看 | 中文字幕一区二区三区在线观看 | 国产欧美一区二区三区在线播放 | 国产四区 | 粉嫩av久久一区二区三区 | 国产精品美女久久久久久不卡 | 特级特黄特色的免费大片 | 草久久| 羞羞的视频免费在线观看 | 久久亚洲一区 | 午夜国产精品视频 | av网站免费 | 一级高清视频 | 久久99精品国产 | 欧美中文视频 | 久久精品免费观看 | 久久国产高清 | 91视频网址 | 成人一区二区视频 | 狠狠天天 | 三级高清 | 久久精品日产第一区二区三区 | 九九福利 | 久久综合一区二区三区 | 亚洲成年人免费网站 | 国产一区二区三区在线 | 国产在线小视频 | 国产欧美久久精品 | 亚洲精品日本 | 久久久久亚洲精品 | 欧美激情视频一区二区三区在线播放 | av不卡一区 | 91麻豆精品国产91久久久资源速度 | 男女爱爱福利视频 | 伊人伊成久久人综合网站 | 盗摄精品av一区二区三区 | 天天干天天插 | 欧美一级淫片免费视频黄 | 亚洲v区 | 精品91久久久 |