欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java 高并發(fā)一:前言

 更新時間:2016年09月09日 16:56:01   作者:Hosee  
本系列基于煉數(shù)成金課程,為了更好的學習,做了系列的記錄。 本文主要介紹 1.高并發(fā)的概念,為以后系列知識做鋪墊。 2.兩個重要的定理

1、關于高并發(fā)的幾個重要概念

1.1 同步和異步

首先這里說的同步和異步是指函數(shù)/方法調(diào)用方面。

很明顯,同步調(diào)用會等待方法的返回,異步調(diào)用會瞬間返回,但是異步調(diào)用瞬間返回并不代表你的任務就完成了,他會在后臺起個線程繼續(xù)進行任務。

1.2 并發(fā)和并行

并發(fā)和并行在外在表象來說,是差不多的。由圖所示,并行則是兩個任務同時進行,而并發(fā)呢,則是一會做一個任務一會又切換做另一個任務。所以單個cpu是不能做并行的,只能是并發(fā)。

1.3 臨界區(qū)

臨界區(qū)用來表示一種公共資源或者說是共享數(shù)據(jù),可以被多個線程使用,但是每一次,只能有一個線程使用它,一旦臨界區(qū)資源被占用,其他線程要想使用這個資源,就必須等待。

1.4 阻塞和非阻塞

阻塞和非阻塞通常形容多線程間的相互影響。比如一個線程占用了臨界區(qū)資源,那么其它所有需要這個資源的線程就必須在這個臨界區(qū)中進行等待,等待會導致線程掛起。這種情況就是阻塞。此時,如果占用資源的線程一直不愿意釋放資源,那么其它所有阻塞在這個臨界區(qū)上的線程都不能工作。

非阻塞允許多個線程同時進入臨界區(qū)

所以阻塞的方式,一般性能不會太好。根據(jù)一般的統(tǒng)計,如果一個線程在操作系統(tǒng)層面被掛起,做了上下文切換了,通常情況需要8W個時間周期來做這個事情。

1.5 死鎖、饑餓、活鎖

所謂死鎖:是指兩個或兩個以上的進程在執(zhí)行過程中,由于競爭資源或者由于彼此通信而造成的一種阻塞的現(xiàn)象,若無外力作用,它們都將無法推進下去。此時稱系統(tǒng)處于死鎖狀態(tài)或系統(tǒng)產(chǎn)生了死鎖,這些永遠在互相等待的進程稱為死鎖進程。就如同下圖中的車都想前進,卻誰都無法前進。

但是死鎖雖說是不好的現(xiàn)象,但是它是一個靜態(tài)的問題,一旦發(fā)生死鎖,進程被卡死,cpu占有率也是0,它不會占用cpu,它會被調(diào)出去。相對來說還是比較好發(fā)現(xiàn)和分析的。

與死鎖相對應的是活鎖。

活鎖,指事物1可以使用資源,但它讓其他事物先使用資源;事物2可以使用資源,但它也讓其他事物先使用資源,于是兩者一直謙讓,都無法使用資源。

舉個例子,就如同你在街上遇到個人,剛好他朝著你的反方向走,與你正面碰到,你們都想讓彼此過去。你往左邊移,他也往左邊移,兩人還是無法過去。這時你往右邊移,他也往右邊移,如此循環(huán)下去。

一個線程在取得了一個資源時,發(fā)現(xiàn)其他線程也想到這個資源,因為沒有得到所有的資源,為了避免死鎖把自己持有的資源都放棄掉。如果另外一個線程也做了同樣的事情,他們需要相同的資源,比如A持有a資源,B持有b資源,放棄了資源以后,A又獲得了b資源,B又獲得了a資源,如此反復,則發(fā)生了活鎖。

活鎖會比死鎖更難發(fā)現(xiàn),因為活鎖是一個動態(tài)的過程。

饑餓是指某一個或者多個線程因為種種原因無法獲得所需要的資源,導致一直無法執(zhí)行。

1.6 并發(fā)級別

并發(fā)級別:阻塞和非阻塞(非阻塞分為無障礙、無鎖、無等待)

1.6.1 阻塞

當一個線程進入臨界區(qū)后,其他線程必須等待

1.6.2 無障礙

  1. 無障礙是一種最弱的非阻塞調(diào)度
  2. 自由出入臨界區(qū)
  3. 無競爭時,有限步內(nèi)完成操作
  4. 有競爭時,回滾數(shù)據(jù)

和非阻塞調(diào)度相比呢,阻塞調(diào)度是一種悲觀的策略,它會認為說一起修改數(shù)據(jù)是很有可能把數(shù)據(jù)改壞的。而非阻塞調(diào)度呢,是一種樂觀的策略,它認為大家修改數(shù)據(jù)未必把數(shù)據(jù)改壞。但是它是一種寬進嚴出的策略,當它發(fā)現(xiàn)一個進程在臨界區(qū)內(nèi)發(fā)生了數(shù)據(jù)競爭,產(chǎn)生了沖突,那么無障礙的調(diào)度方式則會回滾這條數(shù)據(jù)。

在這個無障礙的調(diào)度方式當中,所有的線程都相當于在拿去一個系統(tǒng)當前的一個快照。他們一直會嘗試拿去的快照是有效的為止。

1.6.3 無鎖

是無障礙的

保證有一個線程可以勝出

與無障礙相比,無障礙并不保證有競爭時一定能完成操作,因為如果它發(fā)現(xiàn)每次操作都會產(chǎn)生沖突,那它則會不停地嘗試。如果臨界區(qū)內(nèi)的線程互相干擾,則會導致所有的線程會卡死在臨界區(qū),那么系統(tǒng)性能則會有很大的影響。

而無鎖增加了一個新的條件,保證每次競爭有一個線程可以勝出,則解決了無障礙的問題。至少保證了所有線程都順利執(zhí)行下去。

下面代碼是Java中典型的無鎖計算代碼

無鎖在Java中很常見

while (!atomicVar.compareAndSet(localVar, localVar+1)) 
{ 
 localVar = atomicVar.get(); 
}

1.6.4 無等待

無鎖的

要求所有的線程都必須在有限步內(nèi)完成

無饑餓的

首先無等待的前提是無鎖的基礎上的,無鎖它只保證了臨界區(qū)肯定有進也有出,但是如果進的優(yōu)先級都很高,那么臨界區(qū)內(nèi)的某些優(yōu)先級低的線程可能發(fā)生饑餓,一直出不了臨界區(qū)。那么無等待解決了這個問題,它保證所有的線程都必須在有限步內(nèi)完成,自然是無饑餓的。

無等待是并行的最高級別,它能使這個系統(tǒng)達到最優(yōu)狀態(tài)。

無等待的典型案例:

如果只有讀線程,沒有線線程,那么這個則必然是無等待的。

如果既有讀線程又有寫線程,而每個寫線程之前,都把數(shù)據(jù)拷貝一份副本,然后修改這個副本,而不是修改原始數(shù)據(jù),因為修改副本,則沒有沖突,那么這個修改的過程也是無等待的。最后需要做同步的只是將寫完的數(shù)據(jù)覆蓋原始數(shù)據(jù)。

由于無等待要求比較高,實現(xiàn)起來比較困難,所以無鎖使用得會更加廣泛一些。

2. 有關并行的兩個重要定律

這兩個定律都與加速比有關

2.1 Amdahl定律

定義了串行系統(tǒng)并行化后的加速比的計算公式和理論上限

加速比定義:加速比=優(yōu)化前系統(tǒng)耗時/優(yōu)化后系統(tǒng)耗時

舉個例子:

加速比=優(yōu)化前系統(tǒng)耗時/優(yōu)化后系統(tǒng)耗時=500/400=1.25

這個定理表明:增加CPU處理器的數(shù)量并不一定能起到有效的作用 提高系統(tǒng)內(nèi)可并行化的模塊比重,合理增加并行處理器數(shù)量,才能以最小的投入,得到最大的加速比。

2.2 Gustafson定律

說明處理器個數(shù),串行比例和加速比之間的關系

則加速比=n-F(n-1) //推導過程略

只要有足夠的并行化,那么加速比和CPU個數(shù)成正比

相關文章

最新評論