成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

并發(fā)編程 - 探索一

pcChao / 2995人閱讀

摘要:并發(fā)表示在一段時間內(nèi)有多個動作存在。并發(fā)帶來的問題在享受并發(fā)編程帶來的高性能高吞吐量的同時,也會因為并發(fā)編程帶來一些意想不到弊端。并發(fā)過程中多線程之間的切換調(diào)度,上下文的保存恢復(fù)等都會帶來額外的線程切換開銷。

0x01 什么是并發(fā)

要理解并發(fā)首選我們來區(qū)分下并發(fā)和并行的概念。

并發(fā):表示在一段時間內(nèi)有多個動作存在。
并行:表示在同一時間點有多個動作同時存在。

例如:
此刻我正在寫博客,但是我寫著寫著停下來吃一下東西(菠蘿片)再寫、再吃。這兩個動作在一段時間內(nèi)都在發(fā)生著,這可以理解為并發(fā)。
另一方面我在寫這個博客的同時我在聽音樂。那么同時存在的兩個動作(寫博客、聽音樂)是同時在發(fā)生的這就是所謂的并行。

從上面兩個概念明顯可以感受到并發(fā)是包含并行操作。所以我們通常說的并發(fā)編程對于cpu來說有可能是并發(fā)的在執(zhí)行也有可能是交替的在執(zhí)行。

說到這里你可能會問為什么我們需要并發(fā)編程?
在求解單個問題的時候凡是涉及多個執(zhí)行流程的編程模式都叫并發(fā)編程。

0x02 為什么需要并發(fā)

硬件的發(fā)展推動軟件的進度,多核時代的到來

應(yīng)用系統(tǒng)對性能和吞吐量的苛刻要求

大數(shù)據(jù)時代的到來

移動互聯(lián)網(wǎng)、云計算對計算體系的沖擊

0x03 并發(fā)編程方式

Java:多進程/多線程的并發(fā)實現(xiàn)方式

Go:協(xié)程--用戶態(tài)實現(xiàn)的多線程方式(goroutine)

Java并發(fā)模型

在介紹java并發(fā)模型前我們來介紹下系統(tǒng)對多線程的實現(xiàn)方式。系統(tǒng)支持用戶態(tài)線程和內(nèi)核態(tài)兩種線程的實現(xiàn)方式,內(nèi)核態(tài)線程是cpu去調(diào)度的最小單位,所以這牽涉到用戶態(tài)線程和內(nèi)核態(tài)線程之間的映射關(guān)系,用戶態(tài)線程:內(nèi)核態(tài)線程 = 1:1 、 N:1 、 M:N。

1:1 這種映射關(guān)系充分利用多核的優(yōu)勢,但是這種方式在用戶態(tài)進行線程切換的過程中都會涉及到內(nèi)核態(tài)線程之間的切換,切換開銷大。(主要涉及內(nèi)核線程運行時上下文的保存與恢復(fù))
N:1 沒法充分利用多核的優(yōu)勢,但是這種由于是用戶態(tài)的內(nèi)存切換不涉及內(nèi)核態(tài)線程之間的切換所以這種映射關(guān)系在線程之間切換代價小。
M:N 這種是上面兩種映射關(guān)系的結(jié)合體,集合了上面兩種映射關(guān)系的優(yōu)勢,但是這也增加了線程之間這種映射關(guān)系的調(diào)度復(fù)雜度。

Java的并發(fā)編程模式是通過1:1這種映射關(guān)系來實現(xiàn)線程之間的并發(fā)調(diào)度。

Go并發(fā)模型

Go的并發(fā)模式是通過M:N這種方式來實現(xiàn)并發(fā)調(diào)度的。
Go調(diào)度器中有三種重要結(jié)構(gòu):M(posix thread)、P(調(diào)度上下文,一般數(shù)量設(shè)置為和機器內(nèi)核數(shù)相同,這樣能充分發(fā)揮機器的并發(fā)性能)、G(goroutine)。

一個調(diào)度上下文可以包含多個Goroutine,多個上下文所以可以所有的Goroutine都能并發(fā)的運行在CPU的多核上面。
如果有Goroutine發(fā)現(xiàn)找不到調(diào)度上下文,就會被放到global runqueue中,等清閑的調(diào)度上下文來撈取它進行調(diào)度。
如果調(diào)度上下文上面掛載的所有Goroutine都已經(jīng)執(zhí)行完畢,此時他會去global runqueue中獲取Goroutine,如果發(fā)現(xiàn)此時沒有獲取到,則會去別的調(diào)度上文中搶Goroutine,一般一次搶都是搶此時被搶調(diào)度上下文的一半Goroutine,確保充分利用M去被多核調(diào)度。

0x04 并發(fā)帶來的問題

在享受并發(fā)編程帶來的高性能、高吞吐量的同時,也會因為并發(fā)編程帶來一些意想不到弊端。

資源的消耗,要管理這么多用戶線程、內(nèi)核線程、用戶線程內(nèi)核線程之間的切換調(diào)度,上下文等等這些都是由于引用了并發(fā)編程所帶來的額外消耗。

并發(fā)過程中多線程之間的切換調(diào)度,上下文的保存恢復(fù)等都會帶來額外的線程切換開銷。

編碼、測試的復(fù)雜性。和我們生活中的例子很相像,三五個人一起出去活動很容易把控,如果帶著幾十、上百人的團隊出去活動這些都會帶來額外的管理上的開銷。

真的是有陽關(guān)的地方就有黑暗??!

上面這些都是我們沒法避免的一些問題,要引用并發(fā)編程必然會要付出點額外的代價才行。但是并發(fā)編程還帶來了一個不能忽視的問題,線程之間對同一資源的競爭訪問,造成內(nèi)存對象狀態(tài)和自己的想象千差萬別。

Java線程和內(nèi)存對象之間的交互

java線程對內(nèi)存的理解分為兩部分:線程工作內(nèi)存(每個線程獨有的)、共享內(nèi)存也叫主內(nèi)存(所有的線程所共有的),下面是java線程對內(nèi)存中Count對象的一次修改操作。

從主線程中讀取Count對象放入線程工作內(nèi)存,后面的讀取修改都在線程工作內(nèi)存中,最后(更新到主內(nèi)存的時間不是確定的,可能會插入別的操作在store、write之間)更新到主內(nèi)存中。所有的上述操作都是順序執(zhí)行的,但是不保證連續(xù)執(zhí)行。

volatile變量、synchronized同步塊

volatile變量、synchronized塊執(zhí)行結(jié)束后能保證每次去更新的值都會立即寫入到主內(nèi)存中。
volatile變量很多人會認為這樣就是線程安全的,但是通過上面我們可以看到如果兩個線程同時去讀了一個volatile變量,最后一前一后更新到主內(nèi)存中,這樣也會出現(xiàn)寫丟失的情況,所以volatile不能保證線程安全。

0x05 并發(fā)實戰(zhàn)

1) 定義線程池

private static final ExecutorService executor = Executors.newFixedThreadPool(20);

2)定義并發(fā)服務(wù)

CompletionService completionService = new 
      ExecutorCompletionService(executor);

3)提交并發(fā)任務(wù)

completionService.submit(new Callable() {
    @Override
    public void call() throws Exception {
        return ;
    }
});

4)等待并發(fā)結(jié)果

for (int i = 0; i < taskSize; ++i) {
    Future future = completionService.poll(TIME_OUT,
                    TimeUnit.SECONDS);
    Result result = future.get();
}

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/70030.html

相關(guān)文章

  • 長文慎入-探索Java并發(fā)編程與高并發(fā)解決方案

    摘要:所有示例代碼請見下載于基本概念并發(fā)同時擁有兩個或者多個線程,如果程序在單核處理器上運行多個線程將交替地換入或者換出內(nèi)存這些線程是同時存在的,每個線程都處于執(zhí)行過程中的某個狀態(tài),如果運行在多核處理器上此時,程序中的每個線程都 所有示例代碼,請見/下載于 https://github.com/Wasabi1234... showImg(https://upload-images.jians...

    SimpleTriangle 評論0 收藏0
  • 淺談Java并發(fā)編程系列()—— 如何保證線程安全

    摘要:比如需要用多線程或分布式集群統(tǒng)計一堆用戶的相關(guān)統(tǒng)計值,由于用戶的統(tǒng)計值是共享數(shù)據(jù),因此需要保證線程安全。如果類是無狀態(tài)的,那它永遠是線程安全的。參考探索并發(fā)編程二寫線程安全的代碼 線程安全類 保證類線程安全的措施: 不共享線程間的變量; 設(shè)置屬性變量為不可變變量; 每個共享的可變變量都使用一個確定的鎖保護; 保證線程安全的思路: 1. 通過架構(gòu)設(shè)計 通過上層的架構(gòu)設(shè)計和業(yè)務(wù)分析來避...

    mylxsw 評論0 收藏0
  • 精讀《前端未來展望》

    摘要:精讀前端可以從多個角度理解,比如規(guī)范框架語言社區(qū)場景以及整條研發(fā)鏈路。同是前端未來展望,不同的文章側(cè)重的格局不同,兩個標題相同的文章內(nèi)容可能大相徑庭。作為使用者,現(xiàn)在和未來的主流可能都是微軟系,畢竟微軟在操作系統(tǒng)方面人才儲備和經(jīng)驗積累很多。 1. 引言 前端展望的文章越來越不好寫了,隨著前端發(fā)展的深入,需要擁有非常寬廣的視野與格局才能看清前端的未來。 筆者根據(jù)自身經(jīng)驗,結(jié)合下面幾篇文章...

    MadPecker 評論0 收藏0
  • 函數(shù)式編程與面向?qū)ο?em>編程[5]:編程的本質(zhì)

    摘要:函數(shù)式編程與面向?qū)ο缶幊叹幊痰谋举|(zhì)之劍目錄編程的本質(zhì)讀到兩篇文章寫的不錯綜合摘錄一下復(fù)合是編程的本質(zhì)函數(shù)式程序員在洞察問題方面會遵循一個奇特的路線。在面向?qū)ο缶幊讨?,類或接口的聲明就是表面? 函數(shù)式編程與面向?qū)ο缶幊蘙5]:編程的本質(zhì) 之劍 2016.5.6 01:26:31 編程的本質(zhì) 讀到兩篇文章,寫的不錯, 綜合摘錄一下 復(fù)合是編程的本質(zhì) 函數(shù)式程序員在洞察問題方面會遵循...

    miracledan 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<