測試小花花重口味java多執行緒,慎入。。。。。

花川太美了發表於2017-10-23

下面內容,參考《Java高併發程式設計》書籍。

寫在前面:能不用多執行緒就不用多執行緒,我們的分散式架構,已經是物理多執行緒了。

Tip1:併發與並行:

併發是存在臨界區競爭的,巨集觀上同時,微觀上有先後,所以,才有鎖的概念。去東莞,進了屋,要上鎖。完事了,出門釋放鎖,下一個哥們再來。

艹,本來要寫一篇正經的,又下道兒了。。。。。。

並行是兩條平行線,比如多核CPU就是並行的,單核的就不行,一次cpu只能執行一個命令,所謂一心不能二用。

Tip2:死鎖,活鎖

死鎖:哥在廁所玩手機,心想沒人敲門我就不出來,門外KK很有禮貌,門不開,就不進去。然後我倆就相互等待,最後我得了痔瘡,KK拉了褲襠…….

活鎖:哥和DD一起去廁所,發現就一個坑,我說你先來,他說你先來,我說你先來,他說你先來,我說你先來,他說你先來…… 最後我們都拉了褲襠

Tip3:併發控制策略

阻塞:大號一般都有鎖,完事兒了,開門解鎖,下一個繼續,門外等的一般都拿起手機,被掛起。

無飢餓:無論多牛逼,優先順序多高的人物,沒有特殊通道,必須乖乖排隊,這樣所有的人都可以去廁所,沒有人餓著。小米搶手機….

無阻礙:到斯卡拉小包間兒不鎖門,YY推門一進來,老妹兒就說,大哥旁邊看一會兒,現在都在忙呀。YY急的不行,隔會兒就問快點兒,好沒,好沒。。。。等同於樂觀鎖。

無等待:哥們去買上好的玉鐲,只有一對兒,好幾個買主。這時店主很聰明,做了一堆仿品,讓我們幾個先看著,最終哪個確認買了,在給誰真的進行交易。等同於RCU鎖,適用於讀多寫少。

Tip4:要不要多執行緒

amdahl定律:加速比= 優化前系統耗時/優化後系統耗時
如果系統中沒有能可被並行化的程式碼,這多執行緒毫無意義

Tip5:JavaMM的根本特性

原子性:兩個執行緒互相不會干擾對方的操作,如A執行緒int i = 1 B執行緒int i= -1 ,那麼無論如何執行,i 要麼是1 要麼是-1 而32位的long型就不是這樣,會出現很多意外的值。

可見性:指令重排會讓變數的賦值發生順序變化,所以,執行緒之間觀測變數是否有保證,是我們設計多執行緒要考慮的。

有序性:如果不遵循Happen-before原則,比如

class OrderExample
{

int a = 0 ;
boolean flag = false;

public void writer()
{
    a = 1;
    flag = true;
}

public void reader()
{
   if(flag)
      {
init i = a + 1 ;
...
      }
}

}

如果執行緒A先執行writer()方法,接著執行緒B執行reader()方法,如果發生指令重排,即
public void writer()
{

flag = true;
a = 1;

}

那reader 的業務邏輯整個往下就全錯了.

Tip6:基礎的坑坑

1.run和start的區別:run只是執行當前執行緒的預設run方法,如果沒有override的話,啥也不幹,而start才是建立新執行緒,並呼叫每個執行緒預設的run方法呀

2.stop的坑在於終止執行緒的時候,根本不考慮資料一致性,所以,如果你去民政局改名字改到一半,執行緒stop了,舍普琴科就叫舍瓦了。。。

3.sleep只是傻傻的等待,並跑出中斷標記,wait和notify才是可以根據指定的操作物件,進行相互排程,而且wait可以釋放鎖

4.suspend絕對不能用,掛起了也不釋放,如果resume先與其執行,就永遠佔用著資源了

5.join的本質是讓呼叫執行緒等待在當前執行緒的物件例項上,所以就是相親相愛一起走

6.yield就是弱逼,先檢測當前是否有相同優先順序的執行緒處於同可執行狀態,如有,則把CPU的佔有權交給次執行緒,否則繼續執行原來的執行緒,所以yield()方法稱為“退讓”,它把執行機會讓給了同等級的其他執行緒。

7.volatile做不了計數器,僅僅是讓變數每次在使用的時候,都從主存中取。

8.執行緒優先順序僅僅是大多數情況下好用,無法精準控制

9.synchronized濫用的情況就一個原理,用在了你以為大家都玩這一個,其實各玩兒各的。如new物件上,Integer上

10.執行緒不安全的容器使用是多執行緒的大忌,如arrayList,HashMap,原理都是連結串列破壞。。

Tip7:JDK併發包

1.ReentrantLock更加靈活,自定義中斷響應,等待時長

2.公平鎖保證了公平,但付出了管理佇列的代價

下面什麼訊號量,讀寫鎖,執行緒池,未完待續。。。。。


相關文章