Java基礎又核心的高併發知識synchronized-對象鎖

首先用一句通俗易懂的話來簡單概括下java的synchronized的作用:

保證在同一時刻,只有一個線程執行某段代碼,以達到併發安全的效果。

synchronized主要有兩大類用法,對象鎖和類鎖。這兩類用法每類又細分為兩種小分類用法。下面分別介紹如下:

對象鎖又分為基本方法對象鎖和代碼塊鎖.

  1. 對象鎖-同步代碼塊鎖基本用法,即用synchronized()關鍵字修飾的java代碼塊,括號中的參數通常默認傳遞this,即自身所在對象(當然也可以傳遞任意一個自定義的Object對象)。如下圖所示演示同時啟動兩個線程,模擬一個計數器計數案例。如果不用synchronized同步鎖修飾的話,執行的計數器結果就會有問題,因為兩個線程併發訪問,計數器數據互相篡改,導致最終結果比實際小。
Java基礎又核心的高併發知識synchronized-對象鎖

對象鎖-同步代碼塊鎖用法

Java基礎又核心的高併發知識synchronized-對象鎖

同時啟動兩個線程併發請求

2.對象鎖-同步基本方法鎖用法,即用synchronized關鍵字修飾的java普通方法,注意此處說的普通方法是指除了靜態方法(static)修飾的方法以外的其它方法,至於為什麼是除了static靜態方法以外的方法,後面說到類鎖的時候會和大家解釋。如下所示:

Java基礎又核心的高併發知識synchronized-對象鎖

對象鎖-普通方法鎖

同樣和第一種情況,啟動兩個線程同時計數,最終也能保證併發同步的效果。這邊的main方法和第一種情況寫法一樣就不重複貼圖了。好了,此處就已經很詳細的介紹完synchronized的對象鎖的兩種基本用法了。由於篇幅有限,下面再單獨額外介紹下synchronized的類鎖的兩種用法,喜歡的小夥伴或絕對本篇文章對您的學習和認知有一丟丟幫助的話,可以點個關注或留言互相交流學習,有不明白的地方可以隨時留言聯繫我。

結尾補充說明:為什麼這邊如果開兩個線程同時計數的話,如果不用線程同步鎖的話,統計出來的結果會不正確比實際小呢?大家可以轉動下腦筋思考下。。。因為:程序在執行count++這句計數的代碼時候,雖然只是一句簡單的count++,但實際上底層所做的操作遠遠不止表面上看的那麼簡單。執行過程如下:1:從內存獲取最新count值,2:將count值加1,3:將最新的count值再寫入內存。這個時候,如果是多個線程同時執行的話,會造成再第三部的最新count還未寫入內存的時候,另一個線程已經執行了,也就是取的count不是最新的+1過後的值。所以就造成了最終的統計結果不正確。


分享到:


相關文章: