天天看點

【Java并發】——基礎知識梳理(一)Java并發基礎知識

目錄

Java并發基礎知識

1.并發程式設計的優缺點

1.1為什麼要用到并發

1.2并發程式設計的缺點

1.3易混淆的概念

Java并發基礎知識

1.并發程式設計的優缺點

1.1為什麼要用到并發

  • 充分利用多核CPU的運算能力
  • 友善業務拆分

1.2并發程式設計的缺點

(1)頻繁的切換上下文

時間片是CPU配置設定給各個線程的時間,因為時間非常短,是以CPU不斷通過切換線程,讓我們覺得多個線程是同時執行的,時間片一般是幾十毫秒。而每次切換時,需要儲存目前的狀态起來,以便能夠進行恢複先前狀态,而這個切換時非常損耗性能,過于頻繁反而無法發揮出多線程程式設計的優勢。通常減少上下文切換可以采用無鎖并發程式設計,CAS算法,使用最少的線程和使用協程。

  • 無鎖并發程式設計:可以參照concurrentHashMap鎖分段的思想,不同的線程處理不同段的資料,這樣在多線程競争的條件下,可以減少上下文切換的時間。
  • CAS算法,利用Atomic下使用CAS算法來更新資料,使用了樂觀鎖,可以有效的減少一部分不必要的鎖競争帶來的上下文切換
  • 使用最少線程:避免建立不需要的線程,比如任務很少,但是建立了很多的線程,這樣會造成大量的線程都處于等待狀态
  • 協程:在單線程裡實作多任務的排程,并在單線程裡維持多個任務間的切換

由于上下文切換也是個相對比較耗時的操作,是以在”java并發程式設計的藝術”一書中有過一個實驗,并發累加未必會比串行累加速度要快。 可以使用Lmbench3測量上下文切換的時長 vmstat測量上下文切換次數

(2)線程安全問題

多線程程式設計中最難以把握的就是臨界區線程安全問題,稍微不注意就會出現死鎖的情況,一旦産生死鎖就會造成系統功能不可用。

1.3易混淆的概念

(1)同步vs異步

同步和異步通常用來形容一次方法調用。同步方法調用一開始,調用者必須等待被調用的方法結束後,調用者後面的代碼才能執行。而異步調用,指的是,調用者不用管被調用方法是否完成,都會繼續執行後面的代碼,當被調用的方法完成後會通知調用者。比如,在逾時購物,如果一件物品沒了,你得等倉庫人員跟你調貨,直到倉庫人員跟你把貨物送過來,你才能繼續去收銀台付款,這就類似同步調用。而異步調用了,就像網購,你在網上付款下單後,什麼事就不用管了,該幹嘛就幹嘛去了,當貨物到達後你收到通知去取就好。

(2)并發vs并行

并發和并行是十分容易混淆的概念。并發指的是多個任務交替進行,而并行則是指真正意義上的“同時進行”。實際上,如果系統内隻有一個CPU,而使用多線程時,那麼真實系統環境下不能并行,隻能通過切換時間片的方式交替進行,而成為并發執行任務。真正的并行也隻能出現在擁有多個CPU的系統中。

(3)阻塞vs非阻塞

阻塞和非阻塞通常用來形容多線程間的互相影響,比如一個線程占有了臨界區資源,那麼其他線程需要這個資源就必須進行等待該資源的釋放,會導緻等待的線程挂起,這種情況就是阻塞,而非阻塞就恰好相反,它強調沒有一個線程可以阻塞其他線程,所有的線程都會嘗試地往前運作。

(4)臨界區資源

臨界區用來表示一種公共資源或者說是共享資料,可以被多個線程使用。但是每個線程使用時,一旦臨界區資源被一個線程占有,那麼其他線程必須等待。

繼續閱讀