日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jsr133-第一二章

發(fā)布時(shí)間:2024/4/14 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jsr133-第一二章 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1:介紹

  java虛擬機(jī)支持多線程運(yùn)行。線程代表的就是Thread class。對(duì)用戶來說創(chuàng)建線程的唯一辦法就是創(chuàng)建一個(gè)Thread對(duì)象;每一個(gè)線程都和一個(gè)Thread對(duì)象關(guān)聯(lián)。Thread對(duì)象調(diào)用start()方法就啟動(dòng)了相應(yīng)的線程。

  線程的表現(xiàn),尤其是當(dāng)不能正常同步的時(shí)候,會(huì)變得混亂和違反直覺。這個(gè)規(guī)范說明(指:jsr133)描述了java語言里多線程編寫的語義定義;它包含了這樣的規(guī)則:即定義共享內(nèi)存的讀線程能夠讀到的被多個(gè)寫線程寫入的哪些數(shù)據(jù)。盡管這個(gè)規(guī)范類似于不同硬件架構(gòu)的內(nèi)存模型,但這是一個(gè)java內(nèi)存模型的語義定義(semantics?)。

  這些語義并不是描述一個(gè)多線程程序是如何執(zhí)行的。而是描述了多線程程序允許展現(xiàn)的行為。(the behaviors that multithreaded programs are allowed to exhibit.)

(Any execution strategy that generates only allowed behaviors is an acceptable execution strategy. )任何執(zhí)行策略只要產(chǎn)生的是這個(gè)規(guī)范允許的行為那么它就是可以接受的執(zhí)行策略。

1.1 Locks

  多線程之間的溝通有很多種機(jī)制。最基礎(chǔ)的機(jī)制就是同步(synchronization),使用monitors來實(shí)現(xiàn)的機(jī)制。每個(gè)對(duì)象關(guān)聯(lián)一個(gè)監(jiān)聽器(monitor),一個(gè)線程可以鎖定或者解鎖它。同一時(shí)間只有一個(gè)線程可以持有一個(gè)監(jiān)視器的鎖。任何其他試圖鎖定已經(jīng)被鎖定的監(jiān)視器的線程都會(huì)被阻塞直到他們持有這個(gè)監(jiān)視器的鎖。

  一個(gè)線程t可以鎖定一個(gè)特定的監(jiān)聽器很多次;每一個(gè)解鎖操作對(duì)應(yīng)一次鎖定操作,還原對(duì)象狀態(tài)。

  同步聲明(同步塊)計(jì)算出一個(gè)對(duì)象的引用;然后嘗試執(zhí)行一個(gè)對(duì)該對(duì)象監(jiān)視器的鎖定操作并且直到鎖定完成之前不會(huì)繼續(xù)執(zhí)行。鎖定操作執(zhí)行后,同步聲明中的操作才會(huì)被執(zhí)行。如果同步塊的執(zhí)行完成,不管是正常結(jié)束還是異常終端,同一個(gè)監(jiān)視器鎖的解鎖操作都會(huì)自動(dòng)執(zhí)行。

  一個(gè)同步方法在調(diào)用時(shí)會(huì)自動(dòng)執(zhí)行一個(gè)鎖定操作;在鎖定操作完成之前同步方法的內(nèi)容不會(huì)被執(zhí)行。如果這個(gè)方法是一個(gè)實(shí)例方法,它鎖定的是它被調(diào)用實(shí)例關(guān)聯(lián)的監(jiān)視器(monitor)(也就是:方法體執(zhí)行過程中被稱為this的這個(gè)對(duì)象)。如果是靜態(tài)方法,它鎖定的就是方法聲明所在的類的類對(duì)象對(duì)應(yīng)的監(jiān)視器。同樣的,一旦方法體執(zhí)行結(jié)束,不管是正常的還是異常終止,解鎖操作都會(huì)在同一個(gè)監(jiān)聽器上自動(dòng)執(zhí)行。

  這份聲明文檔(指本文)既不提供也不需要檢測死鎖的條件。那些多線程持有(直接或間接)多個(gè)對(duì)象的鎖的程序應(yīng)該使用常用的避免死鎖的方法,如果有必要的話,就創(chuàng)建更級(jí)別的鎖原語。

  其他機(jī)制,例如讀取和寫入Volatile以及在java.util.concurrent 包中的類,提供了正確同步的可選方法。

1.2 Notation in Examples

  Java內(nèi)存模型并不是根本上基于java語言的面相對(duì)象特性的。為了例子的簡潔、簡易,我們只展示代碼片段而忽略類和方法的定義,或者明確的非關(guān)聯(lián)性。大多數(shù)例子是由兩個(gè)或多個(gè)包括訪問本地變量,共享全局變量或者一個(gè)對(duì)象的字段實(shí)例的狀態(tài)的線程組成。我們一般使用類似r1或者r2這樣的變量名來表明一個(gè)方法或者一個(gè)線程的本地變量。這些變量是不能夠被其他線程訪問的。

?2:Incorrectly Synchronized Programs Exhibit Surprising Behav-iors 錯(cuò)誤的同步程序表現(xiàn)出的違反直覺的行為

  Java語法允許編譯器和cpu以最優(yōu)的性能執(zhí)行,這樣與錯(cuò)誤的同步代碼相互影響,就會(huì)產(chǎn)生一些看上去匪夷所思的行為。

  想一下,例如圖1所示。這個(gè)程序使用本地變量r1和r2 以及 共享變量A和B。 看上去結(jié)果應(yīng)該是:r2 ==2, r1==1 。直覺上,第1步和第3步應(yīng)該最先執(zhí)行。如果第1步先執(zhí)行,那么它就看不到第四部的寫操作。如果第3步先執(zhí)行了,它就看不到第2步執(zhí)行的寫操作。

  如果一些執(zhí)行表現(xiàn)出這樣的行為,那么我們就知道步驟4先于步驟1發(fā)生,步驟1先于步驟2,步驟2先于步驟3,步驟3先于步驟4。事實(shí)上,這是很荒謬的。

  但是,編譯器允許不影響線程獨(dú)立運(yùn)行的情況下,對(duì)任何一個(gè)線程進(jìn)行重排序。如果步驟1和步驟2進(jìn)行了重排序,那么r2 == 2和r1 == 1 這樣的結(jié)果,是不是就有可能發(fā)生了。

  對(duì)于一些程序來說,這樣的行為也許看上去是“broken”。但是,需要被標(biāo)注的是這個(gè)代碼是被恰當(dāng)?shù)耐?#xff1a;

  * ?一個(gè)線程里對(duì)一個(gè)變量有一個(gè)寫操作

  * ?另一個(gè)線程對(duì)同一個(gè)變量的讀操作

  * ?并且這個(gè)讀操作和寫操作并沒有按順序同步

  當(dāng)這樣的情況發(fā)生時(shí),就被叫做 a data race。(譯:一個(gè)數(shù)據(jù)競爭)。當(dāng)代碼包含一個(gè)數(shù)據(jù)競爭,就會(huì)經(jīng)常發(fā)生一些違反直覺的情況。

  一些機(jī)器可能會(huì)產(chǎn)生如圖1那樣的執(zhí)行順序。just-in-time compiler(即時(shí)編譯器)和處理器可能會(huì)重排序代碼。另外,運(yùn)行的虛擬機(jī)的內(nèi)存層級(jí)架構(gòu)也可能使程序出現(xiàn)看上去好像重排序一樣的情況。為了簡單起見,我們會(huì)簡單的像編譯器那樣涉及到任何能夠使代碼重排序的東西。源代碼到字節(jié)碼的轉(zhuǎn)換可能重排序和轉(zhuǎn)變程序,但是必須按照這個(gè)指定的規(guī)范執(zhí)行。

  另一個(gè)結(jié)果異常的例子可以看下圖2。這個(gè)程序也是同步錯(cuò)誤的;在訪問變量過程中,它沒有任何約束的任何順序訪問共享內(nèi)存。

  

  一個(gè)常見編譯器優(yōu)化設(shè)計(jì)到讀取r2的值給r5:因?yàn)樗麄兌甲x取了r1.x的值,并且之間沒有任何其他相關(guān)的寫操作。

  現(xiàn)在考慮這樣一種情況,分配給線程2的r6.x的賦值操作介于線程1的第一次r1.x和r3.x的讀取。如果編譯器決定復(fù)用r2給r5,那么r2和r5的將會(huì)是0,同時(shí)r4將會(huì)是3。從這個(gè)程序的遠(yuǎn)景來看,p.x的值已經(jīng)從0修改成了3,然后又改回來了。

  盡管這樣的結(jié)果看上去很驚訝,但事實(shí)上這是被大多JVM實(shí)現(xiàn)鎖允許的行為。但同時(shí),被JLS和JVMS這樣的傳統(tǒng)的虛擬機(jī)內(nèi)存模型所禁止:這是第一個(gè)舊的JMM(Java內(nèi)存模型: Java Memory Model)需要被替換的標(biāo)志。

?3:Informal Semantics

  當(dāng)代碼被重排序的時(shí)候,一個(gè)程序必須被正確的同步來避免多種類型的違反直覺的行為發(fā)生。使用正確的同步不能保證程序里上述的行為是正確的。但是,使用它允許一個(gè)程序員以一種簡單的途徑來推理出一個(gè)程序的可能行為;一個(gè)正確同步的程序的行為是極少依賴可能的重排序的。沒有正確的同步,非常奇怪的、令人迷惑的和匪夷所思的行為就可能會(huì)出現(xiàn)。

  有兩個(gè)關(guān)鍵的辦法來理解一個(gè)程序是否正確同步了:

  1:Conflicting Accesses (訪問沖突)

    兩個(gè)訪問(讀取或者寫入)同一個(gè)共享字段或者數(shù)組元素,如果其中至少有一個(gè)訪問時(shí)寫入那么就被稱為沖突Conficting。

  2:Happens-Before Relationship?

    兩個(gè)行為如果是happens-before關(guān)系,可以排序。如果一個(gè)行為happens-before另一個(gè)行為

轉(zhuǎn)載于:https://www.cnblogs.com/aquariusm/p/6072531.html

超強(qiáng)干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生

總結(jié)

以上是生活随笔為你收集整理的jsr133-第一二章的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。