黄色网址大全免费-黄色网址你懂得-黄色网址你懂的-黄色网址有那些-免费超爽视频-免费大片黄国产在线观看

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節(jié)點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 常見問題 深入理解原子性操作,提高多線程高并發(fā)性能

深入理解原子性操作,提高多線程高并發(fā)性能

更新時間:2019-09-07 09:00:00 來源:動力節(jié)點 瀏覽2836次

  我們在過去傳統(tǒng)的編程過程中,我們定義一個內(nèi)存中的數(shù)據(jù)類型,用于將數(shù)據(jù)放入內(nèi)存中時,只考慮被單個線程訪問,所以不需要考慮太多,因為它是安全的。

  但當數(shù)據(jù)被多個線程同時操作時,就會出現(xiàn)問題。我們必須同步多個線程對數(shù)據(jù)的訪問,以確保可見性和正確性。

  因為JMM模型中對于多線程并發(fā)操作時,父線程中共享的資源變量是存儲在父線程的內(nèi)存空間里的,而作為子線程,各自有各自的線程空間,我們也稱之為工作線程的內(nèi)存空間,每次操作都會拷貝共享資源的副本到自己的工作線程并操作,在操作完成后,需要將各個工作線程的副本更新會主線程的共享變量中,這個過程造成了各個線程可能讀取的共享變量數(shù)值可能不一致問題。同時一個子線程對共享數(shù)據(jù)的修改,在被更新會父線程空間的變量值時,不能被其它子線程立刻看到,這就出現(xiàn)了操作可見性問題。

  比如我們定義一個普通的計數(shù)器數(shù)據(jù)類型Counter類:

image.png

  這個類在單線程環(huán)境中工作是沒有任何問題的,但是當多個線程訪問同一個計數(shù)器實例時就完全不能工作了。因為并發(fā)操作的每個線程都會拷貝它一個副本到自己的線程空間里進行操作,完成后更新會共享的變量中,這就有可能出現(xiàn)數(shù)據(jù)不一致問題。

  同步鎖操作實現(xiàn)

image.png

  此時我們可以使用對操作方法使用synchronized關(guān)鍵字或者使用volatile關(guān)鍵字進行同步的方式來解決問題。

  這個進行了同步的類可以很好的解決了多個線程并發(fā)訪問它的問題。但是我們知道Synchronized關(guān)鍵字背后的實現(xiàn)原理是對修飾的方法進行鎖定處理,而且這個加鎖和解鎖過程并不是一個輕量級的機制,所有存在很多缺點。

  當多個線程在試著獲取同一個鎖時,大部分線程都會被掛起,在鎖被釋放時才會被重置回來。

  當我們的操作臨界區(qū)比較小,這個開銷就會變得非常大,尤其是當鎖經(jīng)常被獲取并且存在很多爭用時。

  另一個缺點在于其它線程在等待鎖被釋放過程中什么也做不了,如果擁有當前鎖的線程執(zhí)行出現(xiàn)延遲(頁面錯誤或者量子鐘結(jié)束等原因),那么其它線程就會出現(xiàn)長時間得不到執(zhí)行的情況。

  原子操作實現(xiàn)原理

  為了避免這些問題的出現(xiàn),Java推出了非鎖定的算法。該算法不使用鎖機制,而且更具可伸縮性和更好的性能。

  它使用了底層的機器指令的原子性來確保高層操作的原子性。簡單說來就是將高一層級的操作分解成跟底層原子操作層級對應(yīng)的操作,從而讓每一次操作不能被中斷或者竊取。

  我們知道在處理資源爭用時我們一般有兩種思路:

  一種是悲觀模式,就是相信爭用的情況一定會發(fā)生,所以預(yù)先建立防范措施,其中加鎖就是屬于這種悲觀模式的實現(xiàn)。

  另外一種是樂觀模式,我們沿著每次操作都可能會成功也可能會失敗的思路處理,就是如果成功就執(zhí)行完畢,如果出現(xiàn)失敗就再執(zhí)行一次。

  悲觀模式是不管怎樣我先鎖定資源使用的是一種阻塞思維,而原子操作則是不采用鎖定機制,大家都可以訪問的非阻塞思維。

  目前,實際的處理器大都提供了一些指令,它們大大簡化了這種非阻塞算法的實現(xiàn),其中目前使用最多的操作是比較和交換操作(CAS)。

  這種算法的操作原理是它接收三個參數(shù)分別為要操作的內(nèi)存地址,我們預(yù)期的當前要操作的數(shù)值,我們需要它變成的新值。

  它會首先檢查指定內(nèi)存地址的值是否跟當前我們預(yù)期的值相同,如果相同就將它更新為新值,如果跟我們預(yù)期的值不同就放棄本次操作,當本次操作完成時,它會返回指定內(nèi)存地址的值。因此,當多個線程試圖執(zhí)行CAS操作時,一個線程獲勝,其他線程什么也不做。調(diào)用者可以選擇重試或執(zhí)行其他操作。

  其實我們平時經(jīng)常使用這種比較和設(shè)置的操作原理來實現(xiàn)一些其它功能操作,方法原理與CAS完全相同,只是會返回一個布爾值,指示操作是否成功。

  可用的原子操作類型

  在Java5.0之前,開發(fā)人員不能直接使用這個操作,但是在Java5.0中添加了幾個原子變量(int、long、boolean和引用變量)。

  int和long版本也支持數(shù)字操作。JVM使用了有硬件機器,CAS或者使用鎖的Java實現(xiàn)來編譯這些類從而使之成為更好的操作方式。

  AtomicInteger

  AtomicLong

  AtomicBoolean

  AtomicReference

  它們都通過compareAndSet()等方法支持CAS操作,所以它們支持多線程訪問,并且比同步操作有著更好的可伸縮性。

image.png

  這里incrementAndGet()和decrementAndGet()方法是AtomicLong和AtomicInteger類提供的兩個數(shù)值操作。

  另外還有g(shù)etAndDecrement(),getAndIncrement(),getAndAdd(inti)和addAndGet()等可以調(diào)用的安全操作。

  這個版本比同步版本更快,而且線程安全。

  最后,我們只使用compareAndSet()方法實現(xiàn)了一個遵循CAS模式的increment()方法。

  這看起來有些復(fù)雜,但這就是實現(xiàn)非阻塞算法的代價。其思想就是當檢測到?jīng)_突時,我們會重試,直到操作成功。

  這是非阻塞算法的通用模式,我們在非阻塞流NIO操作中會經(jīng)常看到這種模式的使用。

  自定義復(fù)雜原子操作類型

  下面我們舉一個實例來實現(xiàn)一個Stack類:

image.png

image.png

  它確實比在這兩個方法上使用synchronized要復(fù)雜,但是如果存在爭用,它的性能也會更好,即使沒有爭用的情況下,它的性能通常也是不錯的。

  總之,原子變量類是實現(xiàn)非阻塞算法的一種很好的方法,而且也是volatile變量的一個很好的替代方法,因為它們可以提供原子性和可見性。

以上就是動力節(jié)點java培訓(xùn)機構(gòu)介紹的“深入理解原子性操作,提高多線程高并發(fā)性能”的內(nèi)容,希望對正在學(xué)習的你有所幫助,如果有不懂的問題可以登錄動力節(jié)點IT培訓(xùn)官網(wǎng)咨詢在線客服老師。

提交申請后,顧問老師會電話與您溝通安排學(xué)習

免費課程推薦 >>
技術(shù)文檔推薦 >>
主站蜘蛛池模板: 男女一级特黄a大片 | 亚洲精品高清视频 | 丝袜综合 | 天堂成人精品视频在线观 | 国产久爱青草视频在线观看 | www.久久.com | 午夜免费片在线观看不卡 | 国产欧美日韩精品综合 | 暴力调教抖s浪荡总裁受文 白洁性荡生活l六 | 全部免费特黄特色大片视频 | 成人在线免费网站 | 日本黄色录像 | 亚洲国产情侣一区二区三区 | 成人性一级视频在线观看 | 婷婷久久久五月综合色 | 中文字幕欧美日韩 | 欧美国产成人精品一区二区三区 | 日韩欧美一区二区三区视频 | 欧美性xxx久久 | 国产东北男同志videos网站 | 免费女上男下xx00xx动态图 | 亚洲一本视频 | 久久精品国产亚洲a | 日韩精品亚洲人成在线播放 | 国产男女猛烈无遮档免费视频网站 | 91香蕉成人 | 色图欧美 | 国产三级欧美 | 色网站免费视频 | 亚洲国产福利精品一区二区 | 人人看人人搞 | 9299yy看片淫黄大片在线 | 亚洲视频免费一区 | 国产成人高清亚洲一区91 | 午夜福利毛片 | 性欧美激情在线观看 | 中文字幕看片在线a免费 | 国产精品欧美在线不卡 | 看免费毛片天天看 | 亚洲欧美另类日韩 | 日本 片 成人 在线 日本3级网站 |