国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

并發(fā)編程的安全性、活躍性以及性能問題

開發(fā) 前端
并發(fā)編程是一個復雜的技術(shù)領(lǐng)域,微觀上涉及到原子性問題、可見性問題和有序性問題,宏觀則表現(xiàn)為安全性、活躍性以及性能問題。

并發(fā)編程中我們需要注意的問題有很多,主要有三個方面,分別是:安全性問題、活躍性問題和性能問題。下面我就來一一介紹這些問題。

安全性問題

相信你一定聽說過類似這樣的描述:這個方法不是線程安全的,這個類不是線程安全的,等等。

那什么是線程安全呢?其實本質(zhì)上就是正確性,而正確性的含義就是程序按照我們期望的執(zhí)行。

那如何才能寫出線程安全的程序呢?之前已經(jīng)介紹了并發(fā) Bug 的三個主要源頭:原子性問題、可見性問題和有序性問題。也就是說,理論上線程安全的程序,就要避免出現(xiàn)原子性問題、可見性問題和有序性問題。

那是不是所有的代碼都需要認真分析一遍是否存在這三個問題呢?當然不是,其實只有一種情況需要:存在共享數(shù)據(jù)并且該數(shù)據(jù)會發(fā)生變化,通俗地講就是有多個線程會同時讀寫同一數(shù)據(jù)。那如果能夠做到不共享數(shù)據(jù)或者數(shù)據(jù)狀態(tài)不發(fā)生變化,不就能夠保證線程的安全性了嘛。有不少技術(shù)方案都是基于這個理論的,例如線程本地存儲(Thread Local Storage,TLS)、不變模式等等,后面我會詳細介紹相關(guān)的技術(shù)方案是如何在 Java 語言中實現(xiàn)的。

但是,現(xiàn)實生活中,必須共享會發(fā)生變化的數(shù)據(jù),這樣的應(yīng)用場景還是很多的。當多個線程同時訪問同一數(shù)據(jù),并且至少有一個線程會寫這個數(shù)據(jù)的時候,如果我們不采取防護措施,那么就會導致并發(fā) Bug,對此還有一個專業(yè)的術(shù)語,叫做數(shù)據(jù)競爭(Data Race)。比如,前面下面這個個 add10K() 的方法,當多個線程調(diào)用時候就會發(fā)生數(shù)據(jù)競爭,如下所示。

public class Test {

    private long count = 0;

    void add10K() {

        int idx = 0;

        while(idx++ < 10000) {

            count += 1;

        }

    }

}

那是不是在訪問數(shù)據(jù)的地方,我們加個鎖保護一下就能解決所有的并發(fā)問題了呢?顯然沒有這么簡單。例如,對于上面示例,我們稍作修改,增加兩個被 synchronized 修飾的 get() 和 set() 方法, add10K() 方法里面通過 get() 和 set() 方法來訪問 value 變量,修改后的代碼如下所示。對于修改后的代碼,所有訪問共享變量 value 的地方,我們都增加了互斥鎖,此時是不存在數(shù)據(jù)競爭的。但很顯然修改后的 add10K() 方法并不是線程安全的。

public class Test {

    private long count = 0;

    synchronized long get(){

        return count;

    }

    synchronized void set(long v){

        count = v;

    } 

    void add10K() {

        int idx = 0;

        while(idx++ < 10000) {

            set(get()+1)      

        }

    }

}

假設(shè) count=0,當兩個線程同時執(zhí)行 get() 方法時,get() 方法會返回相同的值 0,兩個線程執(zhí)行 get()+1 操作,結(jié)果都是 1,之后兩個線程再將結(jié)果 1 寫入了內(nèi)存。你本來期望的是 2,而結(jié)果卻是 1。

這種問題,有個官方的稱呼,叫競態(tài)條件(Race Condition)。所謂競態(tài)條件,指的是程序的執(zhí)行結(jié)果依賴線程執(zhí)行的順序。例如上面的例子,如果兩個線程完全同時執(zhí)行,那么結(jié)果是 1;如果兩個線程是前后執(zhí)行,那么結(jié)果就是 2。在并發(fā)環(huán)境里,線程的執(zhí)行順序是不確定的,如果程序存在競態(tài)條件問題,那就意味著程序執(zhí)行的結(jié)果是不確定的,而執(zhí)行結(jié)果不確定這可是個大 Bug。

在并發(fā)場景中,程序的執(zhí)行依賴于某個狀態(tài)變量,也就是類似于下面這樣:

if (狀態(tài)變量 滿足 執(zhí)行條件) {
  執(zhí)行操作
}

當某個線程發(fā)現(xiàn)狀態(tài)變量滿足執(zhí)行條件后,開始執(zhí)行操作;可是就在這個線程執(zhí)行操作的時候,其他線程同時修改了狀態(tài)變量,導致狀態(tài)變量不滿足執(zhí)行條件了。當然很多場景下,這個條件不是顯式的,例如前面 addOne 的例子中,set(get()+1) 這個復合操作,其實就隱式依賴 get() 的結(jié)果。

那面對數(shù)據(jù)競爭和競態(tài)條件問題,又該如何保證線程的安全性呢?其實這兩類問題,都可以用互斥這個技術(shù)方案,而實現(xiàn)互斥的方案有很多,CPU 提供了相關(guān)的互斥指令,操作系統(tǒng)、編程語言也會提供相關(guān)的 API。從邏輯上來看,我們可以統(tǒng)一歸為:鎖。。

活躍性問題

所謂活躍性問題,指的是某個操作無法執(zhí)行下去。我們常見的“死鎖”就是一種典型的活躍性問題,當然除了死鎖外,還有兩種情況,分別是“活鎖”和“饑餓”。通過前面的學習你已經(jīng)知道,發(fā)生“死鎖”后線程會互相等待,而且會一直等待下去,在技術(shù)上的表現(xiàn)形式是線程永久地“阻塞”了。

但有時線程雖然沒有發(fā)生阻塞,但仍然會存在執(zhí)行不下去的情況,這就是所謂的“活鎖”。可以類比現(xiàn)實世界里的例子,路人甲從左手邊出門,路人乙從右手邊進門,兩人為了不相撞,互相謙讓,路人甲讓路走右手邊,路人乙也讓路走左手邊,結(jié)果是兩人又相撞了。這種情況,基本上謙讓幾次就解決了,因為人會交流啊。可是如果這種情況發(fā)生在編程世界了,就有可能會一直沒完沒了地“謙讓”下去,成為沒有發(fā)生阻塞但依然執(zhí)行不下去的“活鎖”。

解決“活鎖”的方案很簡單,謙讓時,嘗試等待一個隨機的時間就可以了。

那“饑餓”該怎么去理解呢?所謂“饑餓”指的是線程因無法訪問所需資源而無法執(zhí)行下去的情況。“不患寡,而患不均”,如果線程優(yōu)先級“不均”,在 CPU 繁忙的情況下,優(yōu)先級低的線程得到執(zhí)行的機會很小,就可能發(fā)生線程“饑餓”;持有鎖的線程,如果執(zhí)行的時間過長,也可能導致“饑餓”問題。

解決“饑餓”問題的方案很簡單,有三種方案:一是保證資源充足,二是公平地分配資源,三就是避免持有鎖的線程長時間執(zhí)行。這三個方案中,方案一和方案三的適用場景比較有限,因為很多場景下,資源的稀缺性是沒辦法解決的,持有鎖的線程執(zhí)行的時間也很難縮短。倒是方案二的適用場景相對來說更多一些。

那如何公平地分配資源呢?在并發(fā)編程里,主要是使用公平鎖。所謂公平鎖,是一種先來后到的方案,線程的等待是有順序的,排在等待隊列前面的線程會優(yōu)先獲得資源。

性能問題

使用“鎖”要非常小心,但是如果小心過度,也可能出“性能問題”。“鎖”的過度使用可能導致串行化的范圍過大,這樣就不能夠發(fā)揮多線程的優(yōu)勢了,而我們之所以使用多線程搞并發(fā)程序,為的就是提升性能。

所以使用鎖的時候一定要關(guān)注對性能的影響。 那怎么才能避免鎖帶來的性能問題呢?這個問題很復雜,Java SDK 并發(fā)包里之所以有那么多東西,有很大一部分原因就是要提升在某個特定領(lǐng)域的性能。

不過從方案層面,我們可以這樣來解決這個問題。

第一,既然使用鎖會帶來性能問題,那最好的方案自然就是使用無鎖的算法和數(shù)據(jù)結(jié)構(gòu)了。在這方面有很多相關(guān)的技術(shù),例如線程本地存儲 (Thread Local Storage, TLS)、寫入時復制 (Copy-on-write)、樂觀鎖等;Java 并發(fā)包里面的原子類也是一種無鎖的數(shù)據(jù)結(jié)構(gòu);Disruptor 則是一個無鎖的內(nèi)存隊列,性能都非常好……

第二,減少鎖持有的時間。互斥鎖本質(zhì)上是將并行的程序串行化,所以要增加并行度,一定要減少持有鎖的時間。這個方案具體的實現(xiàn)技術(shù)也有很多,例如使用細粒度的鎖,一個典型的例子就是 Java 并發(fā)包里的 ConcurrentHashMap 1.7,它使用了所謂分段鎖的技術(shù);還可以使用讀寫鎖,也就是讀是無鎖的,只有寫的時候才會互斥。

性能方面的度量指標有很多,我覺得有三個指標非常重要,就是:吞吐量、延遲和并發(fā)量。

  1. 吞吐量:指的是單位時間內(nèi)能處理的請求數(shù)量。吞吐量越高,說明性能越好。
  2. 延遲:指的是從發(fā)出請求到收到響應(yīng)的時間。延遲越小,說明性能越好。
  3. 并發(fā)量:指的是能同時處理的請求數(shù)量,一般來說隨著并發(fā)量的增加、延遲也會增加。所以延遲這個指標,一般都會是基于并發(fā)量來說的。例如并發(fā)量是 1000 的時候,延遲是 50 毫秒。

總結(jié)

并發(fā)編程是一個復雜的技術(shù)領(lǐng)域,微觀上涉及到原子性問題、可見性問題和有序性問題,宏觀則表現(xiàn)為安全性、活躍性以及性能問題。

我們在設(shè)計并發(fā)程序的時候,主要是從宏觀出發(fā),也就是要重點關(guān)注它的安全性、活躍性以及性能。安全性方面要注意數(shù)據(jù)競爭和競態(tài)條件,活躍性方面需要注意死鎖、活鎖、饑餓等問題,性能方面我們雖然介紹了兩個方案,但是遇到具體問題,你還是要具體分析,根據(jù)特定的場景選擇合適的數(shù)據(jù)結(jié)構(gòu)和算法。

要解決問題,首先要把問題分析清楚。同樣,要寫好并發(fā)程序,首先要了解并發(fā)程序相關(guān)的問題。

責任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2021-03-21 23:43:22

線程編程安全

2021-07-03 17:44:34

并發(fā)高并發(fā)原子性

2009-11-30 09:41:38

2010-02-06 10:26:55

Android進程

2017-12-29 15:16:28

2015-05-11 10:42:17

混合云性能混合云安全SLA

2012-12-26 10:53:26

2010-04-14 17:19:51

Oracle數(shù)據(jù)庫

2013-01-11 14:00:18

云存儲云計算云安全

2021-10-31 16:10:50

公有云安全性IT

2020-01-18 08:49:17

目錄安全.ssh木馬

2021-10-19 06:05:20

網(wǎng)站安全網(wǎng)絡(luò)威脅網(wǎng)絡(luò)攻擊

2009-07-21 17:22:05

2012-04-05 09:52:21

開源軟件Linux

2011-03-22 13:50:57

云計算

2018-10-18 05:29:04

物聯(lián)網(wǎng)設(shè)備物聯(lián)網(wǎng)安全IOT

2022-01-18 10:48:12

HTTPS加密安全漏洞

2011-06-30 11:04:05

JTS

2011-01-04 16:20:26

linux安全性

2009-11-23 09:07:14

點贊
收藏

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

久久久久久久av麻豆果冻| 黄色美女网站在线观看| 国产一区二区三区在线观看视频| 午夜综合激情| 免费在线观看av电影| 亚洲一区二区三区午夜| 亚洲欧美色婷婷| 久久综合色天天久久综合图片| www.久久99| 一道本视频在线观看| 奇米四色中文综合久久| 天天操天天干天天综合网| 999久久久91| 午夜在线免费观看视频| 日韩三级电影免费观看| 亚洲最新av在线网站| 久久久国产一区二区三区四区小说| 狠狠一区二区三区| 尤物网站在线| 欧美不卡在线一区二区三区| 日韩电影免费在线观看中文字幕| 99视频精品免费视频| 久久av国产紧身裤| 桃花色综合影院| 色综合视频二区偷拍在线| 色狠狠久久aa北条麻妃| 国产调教视频一区| 北条麻妃国产九九九精品小说 | 亚洲柠檬福利资源导航| 国产精品久久占久久| 日本美女在线中文版| 男人草女人视频| 97国产精品视频| 色婷婷精品久久二区二区蜜臂av | 国产黄色在线观看| 人妻互换免费中文字幕| 欧美亚洲国产另类| 在线精品视频免费播放| 国产精品一区二区三区乱码| 色综合久久中文| 成人在线app| 91淫黄看大片| 国内视频一区二区| 久久精品中文字幕电影| 五月天一区二区| 蜜乳av一区二区| 国产精品网在线观看| 在线观看麻豆| 日韩中文字幕在线视频观看 | 国产九九在线观看| av免费观看久久| 中文国产亚洲喷潮| 欧美日韩亚洲国产一区| 免费高清视频精品| 麻豆一区二区麻豆免费观看| 在线视频婷婷| 老太脱裤让老头玩ⅹxxxx| 91久久久国产精品| 中文字幕在线成人| 日本高清不卡一区| 91免费版在线看| 99精品国产一区二区青青牛奶 | 污视频网站观看| 欧洲精品在线一区| 欧美自拍视频在线| 亚洲精品自拍视频| 欧美丝袜第一区| 91亚洲午夜精品久久久久久| 亚洲国产高清一区二区三区| 免费看久久久| 日韩精品av| 狠狠v欧美ⅴ日韩v亚洲v大胸| 亚洲国产精品无码av| av蓝导航精品导航| 97激碰免费视频| 亚洲欧美激情另类校园| 91福利国产精品| 中文字幕不卡三区| 国产精品一二一区| 国产欧美日韩综合一区在线播放| 波多野结衣欧美| 三妻四妾完整版在线观看电视剧| 性欧美精品孕妇| 欧美性猛交久久久乱大交小说 | 国产亚洲女人久久久久毛片| 欧美综合在线视频观看 | 国产综合在线观看视频| 在线一区二区日韩| 欧美三级三级三级| 亚洲免费伊人电影| 99久久国产综合精品色伊| 99国产精品视频免费观看一公开 | 久久精品视频一区| 免费看精品久久片| 亚洲天堂一区二区三区四区| 欧美视频二区欧美影视| 国产激情视频在线观看| 亚洲日本va中文字幕久久| 天天操天天摸天天爽| 99久re热视频精品98| 欧美久久久久久| 亚洲精品免费在线视频| 欧美在线亚洲一区| 欧美成在线视频| 亚洲视频一区二区| 日韩女优电影在线观看| 在线日韩国产精品| 精品毛片网大全| 亚洲精品乱码久久久久久| 久久久久久久电影| 成人高清视频在线观看| 极品少妇一区二区三区精品视频 | 国产精品资源在线观看| 香蕉国产精品偷在线观看不卡| 99久久久久久中文字幕一区| 婷婷精品在线| 日韩三级不卡| 亚洲网站免费| 激情久久99| 日韩毛片免费观看| 亚洲人成在线网站| 1024在线看片你懂得| caoporn97在线视频| 久草中文在线| 日本在线视频观看| 婷婷成人激情| 777电影在线观看| 国产九九在线| av资源网站在线观看| 啊v在线视频| yiren22综合网成人| 蜜桃成人在线视频| 欧美日韩激情视频一区二区三区| 一二三四社区在线视频| 中文在线√天堂| 青青视频在线观| 触手亚洲一区二区三区| 1024免费在线视频| 色爱综合区网| 国产在线xxx| 一个人看的www视频在线免费观看 一个人www视频在线免费观看 | 在线电影一区二区三区| 欧美日高清视频| 777午夜精品免费视频| 91精品国产综合久久久久| 欧美一级专区免费大片| 日韩欧美国产电影| 日韩成人中文字幕在线观看| 亚洲欧美激情精品一区二区| 伊人久久久久久久久久久久久| 亚洲视频自拍偷拍| 久久手机免费视频| 国产69久久精品成人看| 国产精品自产拍在线观看中文| 国产精品久久久久久久天堂| 成人亲热视频网站| 久99久视频| 国产高清精品软男同| www国产精品内射老熟女| 中文久久久久久| 在线中文字幕观看| 免费在线观看av网站| 原纱央莉成人av片 | 日本成人在线免费视频| 成人短剧在线观看| 国内精品一区视频| 欧美家庭影院| 欧美男女视频| 九九热精品视频在线观看| 五月开心六月丁香综合色啪| 国产亚洲在线| 国产99久久久国产精品潘金网站| 久久欧美中文字幕| 午夜日韩在线观看| 日韩免费福利电影在线观看| 在线观看久久久久久| 欧美一级大片在线免费观看| 亚洲自拍偷拍网址| 亚洲精品日韩精品| 日本成年人网址| 天堂中文字幕在线| av老司机在线观看| 成人av婷婷| 欧美激情五月| 国产a视频精品免费观看| 一区二区三区四区av| 91精品国产综合久久久蜜臀粉嫩| 伊人成人开心激情综合网| 日本高清不卡的在线| 欧美精品欧美精品| 妞干网在线免费视频| 青梅竹马是消防员在线| 日本精品不卡| 欧美黄色录像片| 国产精一品亚洲二区在线视频| 亚洲男人天堂av| 亚洲精品在线免费播放| 性欧美在线看片a免费观看| 国产aⅴ精品一区二区三区黄| 青青草国产精品视频|