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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

编程问答

走进并行世界

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

幾個(gè)概念

同步(Synchronous)和異步(Asynchronous)

同步和異步通常來(lái)形容一次方法調(diào)用。同步方法調(diào)用一旦開(kāi)始,調(diào)用者必須等到方法調(diào)用返回后,才能繼續(xù)執(zhí)行任務(wù)。
異步方法更像一個(gè)消息傳遞,一旦開(kāi)始,方法調(diào)用就會(huì)立即返回,調(diào)用者就可以繼續(xù)后續(xù)的工作。異步方法通常會(huì)在另外的線(xiàn)程中“真實(shí)”的執(zhí)行。整個(gè)過(guò)程不會(huì)阻礙調(diào)用者的工作。

并發(fā)(concurrency)和并行(parallelism)

  • 并發(fā)
    當(dāng)有多個(gè)線(xiàn)程在操作時(shí),如果系統(tǒng)只有一個(gè)CPU,則它根本不可能真正同時(shí)進(jìn)行一個(gè)以上的線(xiàn)程,它只能把CPU運(yùn)行時(shí)間劃分成若干個(gè)時(shí)間段,再將時(shí)間段分配給各個(gè)線(xiàn)程執(zhí)行,在一個(gè)時(shí)間段的線(xiàn)程代碼運(yùn)行時(shí),其它線(xiàn)程處于掛起狀態(tài).這種方式我們稱(chēng)之為并發(fā)(Concurrent).
  • 并行
    當(dāng)系統(tǒng)有一個(gè)以上CPU時(shí),則線(xiàn)程的操作有可能非并發(fā).當(dāng)一個(gè)CPU執(zhí)行一個(gè)線(xiàn)程時(shí),另一個(gè)CPU可以執(zhí)行另一個(gè)線(xiàn)程,兩個(gè)線(xiàn)程互不搶占CPU資源,可以同時(shí)進(jìn)行,這種方式我們稱(chēng)之為并行(Parallel)

  • 多線(xiàn)程在并發(fā)和并行環(huán)境中的不同作用
    在并發(fā)環(huán)境時(shí),多線(xiàn)程不可能真正充分利用CPU,節(jié)約運(yùn)行時(shí)間,它只是以”掛起->執(zhí)行->掛起”的方式以很小的時(shí)間片分別運(yùn)行各個(gè)線(xiàn)程,給用戶(hù)以每個(gè)線(xiàn)程都在運(yùn)行的錯(cuò)覺(jué).在這種環(huán)境中,多線(xiàn)程程序真正改善的是系統(tǒng)的響應(yīng)性能和程序的友好性.
    在并行環(huán)境中, 一個(gè)時(shí)刻允許多個(gè)線(xiàn)程運(yùn)行,這時(shí)多線(xiàn)程程序才真正充分利用了多CPU的處理能力, 節(jié)省了整體的運(yùn)行時(shí)間.在這種環(huán)境中,多線(xiàn)程程序能體現(xiàn)出它的四大優(yōu)勢(shì):充分利用CPU,節(jié)省時(shí)間,改善響應(yīng)和增加程序的友好性.

臨界區(qū)

臨界區(qū)表示一種公共資源或者說(shuō)是共享資源,可以被多個(gè)線(xiàn)程使用。但是每一次只能有一個(gè)線(xiàn)程使用它,一旦臨界區(qū)資源被占用,其他線(xiàn)程要想得到這個(gè)資源就必須等待。
在并行程序中。臨界區(qū)資源是保護(hù)對(duì)象。就比如大家公用的一臺(tái)打印機(jī),必然是一個(gè)人打完另一個(gè)人的才能打印,否則就會(huì)出亂子。

阻塞(blocking)與非阻塞(non-blocking)

阻塞和非阻塞通常來(lái)形容多線(xiàn)程間的相互影響。比如一個(gè)線(xiàn)程占用了臨界區(qū)資源,那么其他所有需要這個(gè)資源的線(xiàn)程都需要在臨界區(qū)中等待。等待會(huì)導(dǎo)致線(xiàn)程掛起,這種情況就是阻塞。此時(shí)如果占用這個(gè)資源的線(xiàn)程一直不愿釋放資源,那么其他所有阻塞在這個(gè)臨界區(qū)上的線(xiàn)程都不能工作。
反之就是非阻塞,它強(qiáng)調(diào)沒(méi)有一個(gè)線(xiàn)程可以妨礙其他線(xiàn)程執(zhí)行。所有線(xiàn)程都會(huì)嘗試不斷前向執(zhí)行。

死鎖(deadlock)、饑餓(starvation)和活鎖(livelock)

這三種情況都屬于線(xiàn)程活躍性問(wèn)題。如果發(fā)現(xiàn)上述情況,那么相關(guān)線(xiàn)程可能就不再活躍,也就是說(shuō)它可能很難再繼續(xù)執(zhí)行任務(wù)了。

  • 死鎖
    應(yīng)該是最糟糕的情況之一。它們彼此相互都占用著其他線(xiàn)程的資源,都不愿釋放,那么這種狀態(tài)將永遠(yuǎn)維持下去。

  • 饑餓
    是指一個(gè)或多個(gè)線(xiàn)程因?yàn)榉N種原因一直無(wú)法得到所需要的資源,導(dǎo)致一直無(wú)法執(zhí)行,比如它的線(xiàn)程優(yōu)先級(jí)太低,高優(yōu)先級(jí)的線(xiàn)程一直搶占它所需要的資源。另一種可能是某一個(gè)線(xiàn)程一直占用著關(guān)鍵資源不放,導(dǎo)致其他需要這個(gè)資源的線(xiàn)程一直無(wú)法得到這個(gè)資源,無(wú)法正常執(zhí)行。與死鎖相比,饑餓還是可能在一段時(shí)間內(nèi)解決的,比如高優(yōu)先級(jí)的線(xiàn)程執(zhí)行完任務(wù)后,不在搶占資源,資源得到釋放。

  • 活鎖
    是非常有趣的情況,也是最難解決的情況。這就比如,大家在一個(gè)兩人寬的橋上走路,雙方都很有禮貌。都在第一時(shí)間禮讓對(duì)方,一個(gè)往左一個(gè)往右,導(dǎo)致兩人都無(wú)法正常通行。放到線(xiàn)程中,就體現(xiàn)為,兩個(gè)線(xiàn)程都拿到資源后都主動(dòng)釋放給他人使用,那么就會(huì)出現(xiàn)資源不斷的在兩個(gè)線(xiàn)程中跳動(dòng),而沒(méi)有一個(gè)線(xiàn)程可以拿到資源后正常執(zhí)行,這個(gè)就是活鎖。

并發(fā)級(jí)別

由于臨界區(qū)的存在,多線(xiàn)程之間的并發(fā)必須受到控制。根據(jù)控制并發(fā)的策略,我們可以把并發(fā)的級(jí)別進(jìn)行分類(lèi),大致上可以分為阻塞、無(wú)饑餓、無(wú)障礙,無(wú)鎖和無(wú)等待幾種。

阻塞(blocking)

一個(gè)線(xiàn)程是阻塞的,那么在其他線(xiàn)程釋放資源之前,當(dāng)前線(xiàn)程無(wú)法繼續(xù)執(zhí)行。當(dāng)我們使用synchronized關(guān)鍵字,或者重入鎖時(shí),我們得到的就是阻塞的線(xiàn)程。
無(wú)論是synchronized還是重入鎖,都會(huì)在視圖執(zhí)行后續(xù)代碼前得到臨界區(qū)的鎖,如果得不到,線(xiàn)程就會(huì)被掛起等待,直到占有了所需要的資源為止。

無(wú)饑餓

如果線(xiàn)程間是有優(yōu)先級(jí)的,那么線(xiàn)程調(diào)用總是會(huì)傾向于滿(mǎn)足高優(yōu)先級(jí)的線(xiàn)程。也就是說(shuō)對(duì)同一個(gè)資源的分配是不公平的。對(duì)于非公平的鎖來(lái)說(shuō),系統(tǒng)允許高優(yōu)先級(jí)的線(xiàn)程插隊(duì),這樣有可能導(dǎo)致低優(yōu)先級(jí)的線(xiàn)程產(chǎn)生饑餓。但如果鎖是公平的,滿(mǎn)足先來(lái)后到,那么饑餓就不會(huì)產(chǎn)生,不管新來(lái)的線(xiàn)程優(yōu)先級(jí)多高,要想獲得資源就必須排隊(duì)。那么所有的線(xiàn)程都有機(jī)會(huì)執(zhí)行。

無(wú)障礙(obstruction-Free)

無(wú)障礙是一種最弱的非阻塞調(diào)度。兩個(gè)線(xiàn)程如果是無(wú)障礙的執(zhí)行,那么他們不會(huì)因?yàn)榕R界區(qū)的問(wèn)題導(dǎo)致一方被掛起。大家都可以大搖大擺進(jìn)入臨界區(qū)工作。那么如果大家都修改了共享數(shù)據(jù)怎么辦呢?對(duì)于無(wú)障礙的線(xiàn)程來(lái)說(shuō),一旦出現(xiàn)這種情況,當(dāng)前線(xiàn)程就會(huì)立即對(duì)修改的數(shù)據(jù)進(jìn)行回滾,確保數(shù)據(jù)安全。但如果沒(méi)有數(shù)據(jù)競(jìng)爭(zhēng)發(fā)生,那么線(xiàn)程就可以順利完成自己的工作,走出臨界區(qū)。
如果阻塞控制的方式比喻成悲觀策略。也就是說(shuō)系統(tǒng)認(rèn)為兩個(gè)線(xiàn)程之間很有可能發(fā)生不幸的沖突,因此,保護(hù)共享數(shù)據(jù)為第一優(yōu)先級(jí)。相對(duì)來(lái)說(shuō),非阻塞的調(diào)度就是一種樂(lè)觀策略,他認(rèn)為多線(xiàn)程之間很有可能不會(huì)發(fā)生沖突,或者說(shuō)這種概率不大,但是一旦檢測(cè)到?jīng)_突,就應(yīng)該回滾。
從這個(gè)策略來(lái)看,無(wú)障礙的多線(xiàn)程程序不一定能順利執(zhí)行。因?yàn)楫?dāng)臨界區(qū)的字眼存在嚴(yán)重的沖突時(shí),所有線(xiàn)程可能都進(jìn)行回滾操作,導(dǎo)致沒(méi)有一個(gè)線(xiàn)程可以走出臨界區(qū)。所以我們希望在這一堆線(xiàn)程中,至少可以有一個(gè)線(xiàn)程可以在有限時(shí)間內(nèi)完成自己的操作,至少這可以保證系統(tǒng)不會(huì)再臨界區(qū)進(jìn)行無(wú)線(xiàn)等待。
一種可行的無(wú)障礙實(shí)現(xiàn)可以依賴(lài)一個(gè)“一致性標(biāo)記”來(lái)實(shí)現(xiàn)。線(xiàn)程在操作之前,先讀取并保持這個(gè)標(biāo)記,在操作完后,再次讀取,檢查這個(gè)標(biāo)記是否被修改過(guò),如果前后一致,則說(shuō)明資源訪問(wèn)沒(méi)有沖突。如果不一致,則說(shuō)明資源可能在操作過(guò)程中與其他寫(xiě)線(xiàn)程沖突,需要重試操作。任何對(duì)保護(hù)資源修改之前,都必須更新這個(gè)一致性標(biāo)記,表示數(shù)據(jù)不安全。

無(wú)鎖(lock-free)

無(wú)鎖的并行都是無(wú)障礙的。在無(wú)鎖的情況下,所有的線(xiàn)程都能?chē)L試對(duì)臨界區(qū)的資源進(jìn)行訪問(wèn),但不同的是,無(wú)鎖的并發(fā)保證必然有一個(gè)線(xiàn)程能夠在有限步內(nèi)完成操作離開(kāi)臨界區(qū)。
在無(wú)鎖的調(diào)度中,一個(gè)典型的特點(diǎn)是可能會(huì)包含一個(gè)無(wú)窮循環(huán)。在這個(gè)循環(huán)中線(xiàn)性不斷嘗試修改共享數(shù)據(jù)。如果沒(méi)有沖突,修改成功,那么線(xiàn)程退出,否則嘗試重新修改。但無(wú)論如何,無(wú)鎖的并行總能保證有一個(gè)線(xiàn)程可以勝出,不至于全軍覆沒(méi)。至于臨界區(qū)中競(jìng)爭(zhēng)失敗的線(xiàn)程,則不斷重試。如果運(yùn)氣不好,總是不成功,則會(huì)出現(xiàn)類(lèi)似饑餓的現(xiàn)象,線(xiàn)程會(huì)停止不前。

無(wú)等待(wait-free)

無(wú)鎖是要求至少有一個(gè)線(xiàn)程在有限步內(nèi)完成操作,而無(wú)等待則是在無(wú)鎖的基礎(chǔ)之上進(jìn)一步擴(kuò)展。他要求所有線(xiàn)程都必須在有限步內(nèi)完成操作。這樣就不會(huì)引起饑餓問(wèn)題。如果限制這個(gè)步驟上限,還可以分為有界無(wú)等待和線(xiàn)程無(wú)關(guān)的無(wú)等待幾種,它們之間的區(qū)別只是對(duì)循環(huán)次數(shù)的限制不同。
一種典型的無(wú)等待結(jié)構(gòu)是RCU(read-copy-update)。它的基本思想是,對(duì)數(shù)據(jù)的讀可以不加控制,因此所有讀線(xiàn)程都是無(wú)等待的,它們既不會(huì)被鎖定等待也不會(huì)引起任何沖突。但在寫(xiě)數(shù)據(jù)時(shí),先取得原始數(shù)據(jù)的副本,接著只修改副本數(shù)據(jù),修改完后,在合適的時(shí)機(jī)回寫(xiě)數(shù)據(jù)。

JMM

JMM的關(guān)鍵技術(shù)點(diǎn)都是圍繞多線(xiàn)程的原子性、可見(jiàn)性與有序性來(lái)建立的。

  • 原子性
  • 可見(jiàn)性
    當(dāng)一個(gè)線(xiàn)程修改了一個(gè)共享變量的值,其他線(xiàn)程是否能夠立即知道這個(gè)修改。
  • 有序性

哪些指令不能重排

程序順序原則:一個(gè)線(xiàn)程內(nèi)保證語(yǔ)義的串行性

volatile規(guī)則:volatile變量的寫(xiě),先發(fā)生與讀,這保證了volatile變量的可見(jiàn)性。

鎖規(guī)則:解鎖(unlock)必然發(fā)生在隨后的加鎖(lock)前

鎖規(guī)則強(qiáng)調(diào),unlock操作必然發(fā)生在后續(xù)的對(duì)同一個(gè)鎖的lock之前,也就是說(shuō),
如果對(duì)一個(gè)鎖解鎖后,在加鎖,那么加鎖的動(dòng)作絕對(duì)不能重排到解鎖動(dòng)作之前。
很顯然,如果這么做,加鎖行為是無(wú)法獲得這把鎖的。

傳遞性:A先于B,B先于C,那么A必然先于C

線(xiàn)程的start()方法先于它的每一個(gè)動(dòng)作

線(xiàn)程的所有操作先于線(xiàn)程的終結(jié)(Thread.join())

線(xiàn)程的中斷(interrupt())先于被中斷線(xiàn)程的代碼

對(duì)象的構(gòu)造函數(shù)執(zhí)行、結(jié)束先于finalize()方法

總結(jié)

以上是生活随笔為你收集整理的走进并行世界的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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