成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

多線程開發(fā)中線程數(shù)量設(shè)計問題

開發(fā) 后端
前面我們用了幾篇文章系統(tǒng)的說了一下有關(guān)Java并發(fā)編程模型中的一些基礎(chǔ)的知識。比如同步,鎖,原子性操作,信號量等以及它們的一些延展實(shí)現(xiàn)閂鎖,柵鎖等等。

 前言

前面我們用了幾篇文章系統(tǒng)的說了一下有關(guān)Java并發(fā)編程模型中的一些基礎(chǔ)的知識。比如同步,鎖,原子性操作,信號量等以及它們的一些延展實(shí)現(xiàn)閂鎖,柵鎖等等。

[[277971]]

今天我們回過頭來簡單說一下并發(fā)編程模型的設(shè)計和選擇。

主要涉及到我們?nèi)绾卫枚嗑€程設(shè)計來在多處理器或者多內(nèi)核時代如何提高我們應(yīng)該程序的性能。

說說線程和應(yīng)用程序之間的關(guān)系,以及我們在編程過程中如何去設(shè)計多線程模型。是不是我們編程時設(shè)計的線程越多對應(yīng)用程序的性能提升越大,什么情況下設(shè)計什么樣的線程模型。

并發(fā)與并行

在具體說多線程并發(fā)模型設(shè)計之前,我們先來簡單澄清兩個概念,并發(fā)(Concurrency)和并行(Parallel),

它們是兩個容易混淆的概念,它們的基礎(chǔ)都是多線程,而并行是指多個進(jìn)程或線程之間在運(yùn)行時同一時間里并行的執(zhí)行。

而并發(fā)則是多個線程一起共同去完成某一項任務(wù)??梢栽趩魏颂幚砥魃戏謺r運(yùn)行實(shí)現(xiàn),也可以在多核處理器上并行運(yùn)行實(shí)現(xiàn)。

所以說并發(fā)偏重于是編程級別的概念,而并行則多指運(yùn)行方式的概念。并行可以是進(jìn)程級別上,多個進(jìn)程同時運(yùn)行,也可以是線程級別的多個獨(dú)立線程的并行運(yùn)行。強(qiáng)調(diào)的是同一時間上的同時發(fā)生。

我們通常所說的并發(fā)編程,實(shí)質(zhì)就是通過多個線程來分解要執(zhí)行的任務(wù),使其成為多個可獨(dú)立執(zhí)行的小任務(wù),做到可以在單核上分時執(zhí)行,也可以在多核上并行執(zhí)行。從而縮短總?cè)蝿?wù)的處理時間,從而提高應(yīng)用程序的性能。

多線程并發(fā)編程模型

在編程領(lǐng)域里,并發(fā)編程設(shè)計其實(shí)是跟順序同步編程或者串行化編程設(shè)計相對的。

串行化編程是將任務(wù)排隊,針對的運(yùn)行它的目標(biāo)處理器只有一個,而且數(shù)單線程處理的。要提高這類應(yīng)用程序的性能,我們只能通過提高該該處理器的執(zhí)行效率來完成,但是它的提升是有限的,畢竟單核的處理能力是有上限的。

當(dāng)我們的計算機(jī)進(jìn)入多內(nèi)核時代后,串行化編程所使用的單線程模型是無法使用多內(nèi)核的,為此我們將應(yīng)用程序的執(zhí)行任務(wù)分解成可獨(dú)立執(zhí)行的小任務(wù),交給多個線程,讓它們在多個內(nèi)核上并行執(zhí)行。

多個處理器或者內(nèi)核并行的執(zhí)行多個線程,能夠很好發(fā)揮并發(fā)編程模型的威力,縮短應(yīng)用代碼的執(zhí)行時間。

這就是為什么我們進(jìn)入多處理器或者多內(nèi)核計算機(jī)時代后,多線程編程成為提高應(yīng)用程序的性能的一個重要的選項。

因?yàn)檫@種設(shè)計能夠給我們帶來極大的應(yīng)用程序性能提高,同時還能增強(qiáng)我們應(yīng)用程序的響應(yīng)性。

當(dāng)然,在單核時代并發(fā)編程模型也能夠在一定程度上提高應(yīng)用程序效率,因?yàn)椴l(fā)編程模型會將一個大的任務(wù)分解成由多個線程負(fù)責(zé)的眾多小任務(wù),在一個單核處理器上借助處理器的分時處理機(jī)制來執(zhí)行,從而有效的利用了任務(wù)執(zhí)行過程中出現(xiàn)的等待時間。

多線程應(yīng)用程序分類

正是由于進(jìn)入多核時代后,每個可用CPU內(nèi)核都可以獨(dú)立處理自己的任務(wù),真正在運(yùn)行時做到了并行,所以在并發(fā)編程模型中,我們將一個大任務(wù)分解為一系列獨(dú)立運(yùn)行的小任務(wù),交給多個CPU內(nèi)核來并行執(zhí)行,從而真正的大大提高了整個應(yīng)用程序的總運(yùn)行效率。

一般情況下,我們在設(shè)計多線程并發(fā)編程模型時會首先考慮將我們的應(yīng)用程序進(jìn)行一個簡單的分類,就是去識別是計算密集型程序還是I/O密集型的應(yīng)用程序。

因?yàn)檫@兩種類型的程序在CPU上執(zhí)行時有很大的不同,如果是計算密集型程序其處理主要集中在從寄存器讀取數(shù)據(jù)進(jìn)行運(yùn)算然后寫入寄存器這樣的過程,由于寄存器緩存的讀寫速度更靠近于CPU內(nèi)部緩存,所以CPU的計算時間可以很好的被利用,不需要進(jìn)行等待和上下文的切換。

而對于IO密集型應(yīng)用程序來說,由于涉及到大量的輸入/輸出操作而這些大多是由專門的輸入輸出設(shè)備來負(fù)責(zé)處理的,由于它們的處理速度跟CPU有太大的差距,造成了CPU過多的等待時間的浪費(fèi)。

為了能夠充分利用現(xiàn)在多處理器或多內(nèi)核的計算機(jī)算力,我們采用多線程并發(fā)設(shè)計編程來提高應(yīng)用程序的性能是必由之路。下面我們舉例說明上面兩種類型應(yīng)用的設(shè)計:

計算密集型應(yīng)用程序多線程設(shè)計

首先看計算密集型應(yīng)用,這種類型的處理,最常見的例子比如我們想處理硬盤上某個文件夾里的圖片大小的應(yīng)用,由于我們可以一次性將相關(guān)數(shù)據(jù)讀入處理的內(nèi)存,接下來重要的就是對數(shù)據(jù)進(jìn)行運(yùn)算處理了,屬于計算密集型處理。

如果是單線程方法來實(shí)現(xiàn)的話,單線程方法需要遍歷所有文件并依次縮放每個圖片。

這種單線程模型下,即使我們有一個具有多個核心的CPU,調(diào)整大小的過程將只使用一個可用的CPU內(nèi)核。

而如果采用多線程方法可以定義一個主線程負(fù)責(zé)掃描文件系統(tǒng)并將所有找到的文件添加到一個隊列中,該隊列由一組工作線程來負(fù)責(zé)處理。

那么這時候就要注意了,這種情況下我們?nèi)绾卧O(shè)計我們的多線程處理模型呢?

我們簡單想一下就知道,計算過程最好是每個CPU綁定特定的線程,不斷的讀取數(shù)據(jù)處理即可。

所以如果我們剛好有與可用CPU內(nèi)核數(shù)一樣多的工作線程,那么我們就能確保每個可用的CPU內(nèi)核在處理圖片時都有事情可做。

充分利用計算機(jī)的算力,也不存在線程上下文切換問題,也不存在等待輸入輸出問題,從而縮短圖片的處理時間,提供整個應(yīng)用程序的性能。

也就是說在我們并發(fā)模型設(shè)計時,如果主要涉及到數(shù)據(jù)的運(yùn)算問題,我們可以設(shè)計跟可以使用的CPU內(nèi)核數(shù)相同的線程數(shù),以綁定執(zhí)行線程的CPU內(nèi)核,來充分的利用空閑的CPU內(nèi)核處理能力。

這種情況下,如果從可擴(kuò)展性考慮,我們可能想通過添加更多資源來提高性能,那么只能通過提高單個CPU算力的角度來實(shí)現(xiàn)。

假如在這個例子中,我們遇到了更大量的圖片需要處理,我們是否能夠?yàn)槲覀兊膽?yīng)用程序添加更多的線程來處理呢?

其實(shí)這種計算密集型應(yīng)用,由于我們當(dāng)前機(jī)器的CPU內(nèi)核數(shù)量有限,添加更多的線程并不能提高性能。

反而由于負(fù)責(zé)調(diào)度的線程必須管理更多的工作線程,并且線程的創(chuàng)建和關(guān)閉也會消耗CPU,而會出現(xiàn)增加越多線程性能反而可能下降的現(xiàn)象。

I/O密集型的應(yīng)用程序多線程設(shè)計

對于輸入/輸出密集型應(yīng)用程序來說,也就是說就是具有大量I/O等待時間的應(yīng)用程序,利用多線程提高應(yīng)用程序整體性能,如何設(shè)計呢?

我們來假想一個例子,假設(shè)我們想要編寫一個應(yīng)用程序,將一個完整的網(wǎng)站內(nèi)容以HTML文件的形式鏡像到硬盤上。因?yàn)樯婕暗骄W(wǎng)絡(luò)訪問,需要大量的網(wǎng)絡(luò)I/O操作。

所以,它是典型的輸入/輸出密集型應(yīng)用。

具體實(shí)現(xiàn)過程怎么做呢?我們需要從這個站點(diǎn)的每一個頁面開始,去搜索其每一個站內(nèi)的鏈接,讓后根據(jù)這些鏈接向其web服務(wù)器發(fā)送訪問請求,由于涉及到網(wǎng)絡(luò)請求,所以請求的響應(yīng)時間就不確定了,某個請求可能需要很長時間才能收到回復(fù)。

同樣,如果我們采用單線程的處理方式,那么這其中的等待回復(fù)時間可能是一個讓人無法忍受的過程。而且在這等待期間,我們的應(yīng)用程序可能啥都做不了。

如果我們可以將這份工作分配到多個線程,讓一個或多個線程負(fù)責(zé)解析請求接收到的HTML頁面,并將找到的鏈接放入隊列,而其他線程則向web服務(wù)器發(fā)出請求,然后等待回復(fù)。如此我們的應(yīng)用程序能夠在新請求頁面的等待時間里來解析已經(jīng)接收的頁面。

而我們知道涉及到網(wǎng)絡(luò)傳輸?shù)妮斎胼敵鲞^程都是由我們的操作系統(tǒng)網(wǎng)卡負(fù)責(zé)的,也就是說我們的應(yīng)用程序的線程只需要負(fù)責(zé)將請求發(fā)送出去,然后等待遠(yuǎn)程的網(wǎng)絡(luò)回復(fù)即可,這等待期間線程可以做別的事情,而不必被阻塞等待。

同時由于我們的CPU要做的基本上就是響應(yīng)一下輸入輸出操作開始和結(jié)束指令,做一些訪問和存儲線程處理工作,大部分時間應(yīng)該都是響應(yīng)事件處理。

此時我們的CPU可用內(nèi)核處理過程是不需要線程綁定的,所以這類IO操作密集類型應(yīng)用多線程時,我們可以在應(yīng)用程序中添加多于可用CPU內(nèi)核數(shù)的線程來充分利用其算力,那么這個應(yīng)用程序甚至可能獲得更好的性能。

簡單來說,應(yīng)用程序的性能意味著能在更短的時間內(nèi)完成更多的任務(wù)。

我們再來看另外一種情況,在我們的圖形用戶界面(GUI)應(yīng)用中,我們常常會遇見需要用戶輸入一些內(nèi)容,然后單機(jī)處理按鈕來提交數(shù)據(jù)給服務(wù)器進(jìn)行處理這樣的操作過程,在這個過程中,當(dāng)我們單機(jī)按鈕后,如果是單線程處理的情況下,應(yīng)用程序會被阻塞,等待服務(wù)器處理的結(jié)果返回。

這時我們一般為了防止用戶重復(fù)提交而將按鈕變成不可用狀態(tài),服務(wù)器在后臺處理數(shù)據(jù)期間用戶就什么也做不了,只能等待服務(wù)器回復(fù)結(jié)果。這樣的用戶體驗(yàn)會很糟糕,如果處理時間稍長一些,鼠標(biāo)都無法移動,就有可能給用戶造成出問題卡死的錯覺。

這個時候,我們完全可以采用多線程來處理,那就是設(shè)計一個額外的線程運(yùn)行等待遠(yuǎn)程服務(wù)器處理結(jié)果,而當(dāng)前的處理線程繼續(xù)相應(yīng)用戶的其它操作請求。

當(dāng)遠(yuǎn)程回復(fù)到達(dá)時,該線程負(fù)責(zé)響應(yīng)。多線程在這類程序中的使用,會給用戶帶來良好的操作體驗(yàn),大大提高應(yīng)用程序的相應(yīng)能力。

總結(jié)

這里我們簡單總結(jié)了一下,在現(xiàn)代多處理器或多內(nèi)核環(huán)境下,如何通過多線程并發(fā)設(shè)計來提高我們應(yīng)用程序的性能和響應(yīng)性。

需要注意的是在設(shè)計時首先要確定我們應(yīng)用程序的類型,是計算密集型還是I/O密集型,如果是計算密集型應(yīng)用,那么我們設(shè)計線程的數(shù)量應(yīng)該等同于我們所能使用的CPU內(nèi)核數(shù),反之,如果是I/O密集型應(yīng)用,我們可以設(shè)置遠(yuǎn)大于可以CPU內(nèi)核數(shù)的線程數(shù)來提高性能。

當(dāng)然,所有的多線程并發(fā)編程模型都離不開對競爭資源的處理,這就需要我們充分的理解同步,鎖,原子性操作,信號量,以及各種衍生的閂鎖,柵鎖等概念,熟練的在設(shè)計過程中對競態(tài)資源進(jìn)行保護(hù)處理了。

責(zé)任編輯:華軒 來源: 今日頭條
相關(guān)推薦

2010-02-01 17:25:09

Python多線程

2015-07-22 09:51:51

iOS開發(fā)線程

2015-07-22 09:39:38

IOS多線程同步

2013-05-23 15:59:00

線程池

2012-02-21 14:14:47

Java

2021-03-05 07:38:52

C++線程編程開發(fā)技術(shù)

2024-04-02 09:53:08

線程池線程堆棧

2009-03-12 10:52:43

Java線程多線程

2023-08-02 09:29:40

任務(wù)池TaskPool

2022-09-06 08:25:13

線程異步任務(wù)

2022-10-11 08:00:47

多線程開發(fā)技巧

2023-08-01 16:35:48

鴻蒙ArkUI應(yīng)用開發(fā)

2011-06-01 11:23:09

Android 線程

2021-06-17 06:57:10

SpringBoot線程池設(shè)置

2009-09-22 17:21:24

線程局部變量

2010-09-17 09:08:49

Java多線程

2009-02-10 09:53:41

多線程程序設(shè)計Java

2010-01-18 14:09:58

C++多線程

2015-12-22 10:39:52

Java多線程問題

2017-01-19 10:24:38

Java多線程問題
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 午夜伦理影院 | 成人免费网视频 | 成年视频在线观看福利资源 | 日日摸日日碰夜夜爽亚洲精品蜜乳 | 91麻豆精品国产91久久久久久 | 91精品国产乱码久久久久久久久 | 国产精品嫩草影院精东 | 国产一区久久久 | 午夜电影日韩 | 国产精品99久久久久久久久久久久 | 欧美日一区二区 | 亚洲精品免费在线观看 | 91精品国产91久久久久久吃药 | 日本精品久久 | 成人精品一区二区三区四区 | 欧美一区二区三区在线观看 | 天天干天天谢 | 毛片免费观看 | 欧美精品一区二区在线观看 | 成人影院av| 色狠狠一区 | 亚洲视频www | 欧美日韩高清在线观看 | 成人永久免费视频 | 亚洲一区视频在线 | 久久国产一区二区三区 | 午夜国产一级片 | 国产精品成人国产乱一区 | 国产黄色大片在线观看 | 五月综合激情网 | 仙人掌旅馆在线观看 | 国产午夜精品一区二区三区四区 | 久久久免费电影 | 久久久精品久 | 九九久久这里只有精品 | 色在线免费 | 国产亚洲精品久久情网 | 国产综合视频 | av一区二区三区四区 | 天天看夜夜 | 国产成人99久久亚洲综合精品 |