国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

Java中線(xiàn)程安全問(wèn)題

發(fā)布時(shí)間:2021-07-06 11:13 來(lái)源:腳本之家 閱讀:0 作者:IT BOY 欄目: 開(kāi)發(fā)技術(shù)

目錄

        一.線(xiàn)程不安全

        多線(xiàn)程的執行環(huán)境中,程序的執行結果和預期的結果不符合,這就稱(chēng)為發(fā)生了線(xiàn)程不安全現象

        二.那些情況導致了線(xiàn)程不安全?

        大致分為以下5種情況:

        (1)CPU搶占執行 (無(wú)法解決);
        (2)非原子性 ;
        (3)編譯器優(yōu)化(指令重排) 編譯器優(yōu)化在單線(xiàn)程下執行沒(méi)問(wèn)題,多線(xiàn)程下優(yōu)化會(huì )發(fā)生混亂;
        (4)內存的不可見(jiàn)性 ;(volatile輕量級解決)
        (5)多個(gè)線(xiàn)程修改了同一個(gè)變量。(方案:讓線(xiàn)程操作自己的變量可以解決該問(wèn)題,但業(yè)務(wù)場(chǎng)景發(fā)生變化,修改難度變大,通用性不高)

        三.Java中解決線(xiàn)程不安全的方案

        1.volatile“輕量級”解決線(xiàn)程不安全

        volatile的出現可以解決上圖所展現的內存不可見(jiàn)問(wèn)題以及禁止指令重排

        實(shí)現原理:工作內存中的變量操作結束后,強制刪除線(xiàn)程工作內存中的變量,起到內存可見(jiàn)注意事項:volatile不能解決原子性問(wèn)題。volatile可以解決線(xiàn)程不安全問(wèn)題是錯誤的(說(shuō)法不夠嚴謹)

        下面兩種方案通過(guò)對關(guān)鍵代碼加鎖,讓cpu排隊執行,鎖操作的步驟為:
        1)嘗試獲取鎖,如果拿到則加鎖,否則排隊等待獲取鎖  2)釋放鎖操作

        2.synchronized自動(dòng)加鎖

        ①synchronized進(jìn)行自動(dòng)加鎖和釋放鎖,是Jvm層面的解決方案

        synchronized使用舉例:使用兩個(gè)線(xiàn)程對變量count進(jìn)行一次++ 和 一次- -

        沒(méi)有使用synchronized上鎖之前,由于非原子問(wèn)題,兩個(gè)線(xiàn)程進(jìn)行++和- -出現線(xiàn)程不安全問(wèn)題,通過(guò)synchronized關(guān)鍵字的使用,解決了非原子問(wèn)題,代碼運行實(shí)際結果和預期結果一致,保證了線(xiàn)程安全。

        ②synchronized實(shí)現原理:

        1.基于操作系統而言,通過(guò)互斥鎖mutex實(shí)現
        2.從Jvm層面來(lái)看,實(shí)現了一個(gè)監視器鎖的加鎖和釋放鎖過(guò)程。

        3.從Java語(yǔ)言本身來(lái)看,存在一個(gè)互斥鎖mutex對象,鎖存在于對象的對象頭中,對象頭中的“偏向線(xiàn)程ID”,表明該鎖被該線(xiàn)程占有,釋放鎖后,偏向線(xiàn)程ID消失。

        mutex結構信息:

        Owner代表鎖的擁有者,為null時(shí)表示鎖未使用;Nest表示鎖的使用次數,為0表示沒(méi)有被使用;此外鎖可以嵌套使用,不會(huì )發(fā)生死鎖情況。

        ③synchronized鎖升級過(guò)程:

        沒(méi)有線(xiàn)程訪(fǎng)問(wèn)時(shí)處于無(wú)鎖狀態(tài) >> 第一個(gè)線(xiàn)程訪(fǎng)問(wèn)時(shí),由無(wú)鎖狀態(tài)轉為偏向鎖 >> 輕量級鎖(其他線(xiàn)程嘗試獲取鎖,鎖處于自旋狀態(tài)) >> 重量級鎖(把沒(méi)有拿到鎖的線(xiàn)程放到等待隊列里面)

        3.Lock手動(dòng)上鎖

        Lock需要程序員自己手動(dòng)上鎖手動(dòng)釋放鎖;Lock是一個(gè)interface;創(chuàng )建鎖時(shí)可以通過(guò)Lock的實(shí)現類(lèi)ReentrantLock()完成:Lock lock = new ReentrantLock();加鎖操作lock.lock(),釋放鎖操作lock.unlock()

        使用Lock需要注意的問(wèn)題:

        一定要把加鎖操作lock()放在try/finally外面如果把lock()放在try中會(huì )導致兩個(gè)問(wèn)題發(fā)生:
        (1)try中代碼出現異常,此時(shí)就會(huì )執行finally中釋放鎖的操作,如果try還沒(méi)有加鎖就去釋放鎖,勢必是不行的。
        (2)try中出現異常后,執行finally中釋放鎖操作,線(xiàn)程狀態(tài)異常會(huì )將try中業(yè)務(wù)異常覆蓋掉,增加了排除錯誤的成本。


        將lock()放在try中第一句可以解決這個(gè)問(wèn)題


        對比發(fā)現,這樣做業(yè)務(wù)異常是不會(huì )被線(xiàn)程的狀態(tài)異常覆蓋的,方便了排查錯誤?。?!

        四.公平鎖與非公平鎖機制

        公平鎖線(xiàn)程按順序執行;非公平鎖沒(méi)有順序,執行效率更高;Java中默認鎖策略為非公平鎖機制synchronized鎖機制:采用非公平鎖機制Lock鎖機制:默認采用非公平鎖機制,但是可以顯示地聲明為公平鎖,比如在創(chuàng )建鎖對象時(shí),在構造方法中傳true:Lock lock = new ReentrantLock(true)

        五.volatile和synchronized的區別

        volatile可以解決內存不可見(jiàn)問(wèn)題以及禁止指令重排序,但是不能解決非原子性問(wèn)題;
        synchronized可以解決大部分線(xiàn)程的非安全問(wèn)題,保證關(guān)鍵代碼排隊執行,無(wú)論何時(shí)鎖只被一個(gè)線(xiàn)程擁有,可解決非原子性問(wèn)題

        六.synchronized和Lock的區別

        1.synchronized自動(dòng)加鎖和釋放鎖,而Lock需要手動(dòng)加鎖和釋放鎖;

        2.synchronized是Jvm層面的實(shí)現,Lock是Java語(yǔ)言層面的實(shí)現;

        3.適用范圍不同:synchronized可以修飾代碼塊(對任意對象加鎖)、修飾靜態(tài)方法(對當前的類(lèi)進(jìn)行加鎖)、修飾普通的方法(對當前的實(shí)例對象進(jìn)行加鎖);而Lock只能修飾代碼塊;

        4.synchronized只有非公平鎖策略;Lock默認采用非公平鎖機制,但可以顯示聲明為公平鎖;

        5.Lock的靈活性更高一些(比如:tryLock)

        到此這篇關(guān)于Java中線(xiàn)程安全問(wèn)題的文章就介紹到這了,更多相關(guān)Java線(xiàn)程安全內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

        免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。

        男女性潮高清免费网站| 性饥渴艳妇性色生活片在线播放| 亚洲AV无一区二区三区久久| 精品人妻一区二区三区四区| 久久精品岛国AV一区二区无码| 久久综合五月丁香久久激情|