java高併發核心要點|系列1|開篇

在java高併發編程,有幾個很重要的內容:java

1.CAS算法算法

2.CPU重排序數據庫

3.緩存行僞共享編程

咱們先來講說高併發世界中的主要關鍵問題是什麼?緩存

是數據共享。多線程

由於多線程之間要共享數據,就會遇到各類問題。以下圖:架構

若是兩個線程同時寫入,那怎麼保證數據的一致性?是線程1先寫,仍是線程2先寫,這是個問題。那要如何解決這個問題?併發

答案是:加鎖。數據庫設計

好比,線程1先訪問共享數據區,那麼它就先把這塊數據區鎖起來。後面若是其餘線程要訪問這個共享區,首先要從線程1這裏獲取鎖,才能進一步訪問這個共享區。這裏很好理解,高併發

其實至關於這樣的情景,你有一個抽屜,抽屜有把鎖,這個鎖的鑰匙,在你手上,你就能夠打開抽屜,往裏面存放或拿取物件。其餘人,要從這個抽屜裏存放東西,必須徵得你的贊成,從你手上拿到鑰匙,而後,他才能用這把鑰匙打開抽屜,進行存放物件的動做。以下圖:

 

 回到高併發的線程世界,咱們知道,能夠用加鎖來解決多線程訪問共享數據區的問題。那問題又來了,那這把鎖,先交給誰呢?怎麼解決這個問題呢?

答案是:鎖競爭。

多線程,若是在優先級同樣的狀況下,你們進行公平競爭?那怎麼樣纔算公平競爭呢?通常狀況下,咱們均可以想到:先到先得。

是的,通常狀況下,操做系統對線程競爭,都取用這個方式,這樣也符合常理。

好,線程1來了,得到一把鎖,對這個共享數據區進行鎖定訪問。那別的線程,只能等待這個線程「辦完事」後,釋放鎖。這時,這些別的線程就進入等待狀態。

如今問題,又來了,若是線程1只是對這個共享數據區進行讀訪問,是否有必要把這個數據區全面鎖定,不讓其餘線程進行讀訪問呢?

沒有必要!

怎麼解決?

讀寫分離!

分別定義兩把鎖,一把讀鎖,一把寫鎖。寫鎖,仍是對寫有獨佔權。讀鎖,就能夠無限量地分發給其餘多個線程。這樣不影響共享數據區的數據一致性。

其實,讀寫分離,是架構設計和數據庫設計中一個很重要的設計思想,也是高性能的一種設計理念。

固然,鎖有不少種,如下就是各類鎖:

優勢

缺點

適用場景

偏向鎖

加鎖和解鎖不須要額外的消耗,和執行非同步方法比僅存在納秒級的差距。

若是線程間存在鎖競爭,會帶來額外的鎖撤銷的消耗。

適用於只有一個線程訪問同步塊場景。

輕量級鎖

競爭的線程不會阻塞,提升了程序的響應速度。

若是始終得不到鎖競爭的線程使用自旋會消耗CPU。

追求響應時間。

同步塊執行速度很是快。

重量級鎖

線程競爭不使用自旋,不會消耗CPU。

線程阻塞,響應時間緩慢。

追求吞吐量。

同步塊執行速度較長。

好了,今天,咱們主要講多線程高併發編程的核心概念:線程鎖。

明天,咱們繼續講鎖的底層實現原理。

相關文章
相關標籤/搜索