中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中synchronized關鍵字的作用分析

發布時間:2021-07-01 15:18:53 來源:億速云 閱讀:416 作者:Leah 欄目:大數據

Java中synchronized關鍵字的作用分析,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

一、簡介:

        synchronized關鍵字是用來控制線程同步的,就是在多線程的環境下,控制synchronized代碼段不被多個線程同時執行。synchronized既可以加在一段代碼上,也可以加在方法上。

1、舉個栗子:

Java中synchronized關鍵字的作用分析

2、類文件編譯

        看看該class文件的編譯后的文件,查看當前類的包,變量信息,堆棧信息等等,有助于理解synchronized到底是什么指令操作的:

命令:javap -verbose MySynchronized > mySynchronized.txt

Java中synchronized關鍵字的作用分析

可以看到jvm加鎖的指令,monitorenter加鎖,monitorexit釋放鎖的指令,至于怎么計數的,有興趣的可以深入研究一下。

二、synchronized的方式概念:

       類鎖,對象鎖,代碼塊鎖,同步方法鎖。

  1. 類鎖:顧名思義是該類的鎖,是初始化靜態方法上的鎖,與對象鎖不一樣,簡單可以理解,類加載完就存在的鎖。

  2. 對象鎖:是new出來的實例,每個實例相互隔離。

  3. 方法鎖:就是方法上加一個synchronized關鍵字,又區分為靜態方法鎖和實例方法鎖,兩者不一樣。

  4. 代碼塊鎖:就是鎖一段代碼,主要區別在括號里的對象synchronized(this){...},或者其他synchronized(lock){...}。

三、鎖的幾種用法和多線程下的阻塞分析

1、代碼塊鎖,新建一個對象:Object lock = new Object(),這里鎖的是這個對象的下的Object 對象,大部分人喜歡這樣用,this是鎖整個對象,范圍比較大,可能造成該對象中其他加鎖方法被干擾,所以可以用這種方式去防止大類對象被使用的時候造成死鎖。

private Object lock = new Object();
/**
* 鎖對象lock
*/
public void methodA(){
   synchronized(lock){
       System.out.println("methodA====start");
       try {
           Thread.sleep(2000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       System.out.println("methodA====end");
   }
}

2、代碼塊鎖,鎖類對象鎖本身,不同的對象相互隔離,互不干擾。

/**
* 鎖對象本身
*/
public void methodB(){
   synchronized(this){
       System.out.println("methodB==start");
       try {
           Thread.sleep(3000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       System.out.println("methodB==end");
   }
}

3、實例方法鎖:

/**
* 實例方法鎖,同一個實例,多線程阻塞
* 不同的實例,互不干擾,因為鎖的不是一個對象
* 不同的實例,不同實例方法鎖,多線程也是阻塞等待的,因為是一個對象
*/
public synchronized void methodD(){
   System.out.println("methodD==start");
   try {
       Thread.sleep(3000);
   } catch (InterruptedException e) {
       e.printStackTrace();
   }
   System.out.println("methodD==end");
}

4、靜態方法鎖:

/**
* static方法,類級別的鎖,更對象this無關,
* 同一個類中靜態方法鎖,多線程阻塞,等待獲取類鎖才能執行
* 同一個類中不同靜態方法鎖,多線程阻塞,也需要等待獲取類鎖才能執行
*/
public synchronized static void methodC(){
   System.out.println("methodC==start");
   try {
       Thread.sleep(3000);
   } catch (InterruptedException e) {
       e.printStackTrace();
   }
   System.out.println("methodC==end");
}

5、最后說說wait和sleep和對象鎖:

/**
* wait 會放棄對象鎖,不會放棄CPU資源
* sleep 不會放棄對象鎖,會放棄CPU資源
* 測試發現同一個對象,sleep的方法阻塞,wait方法會放棄對象 * 鎖,繼續多線程執行
*/
public synchronized void methodE(){
   System.out.println("methodE==start");
   try {
       this.wait(3000);
   } catch (InterruptedException e) {
       e.printStackTrace();
   }
   System.out.println("methodE==end");
}

四、最后總結:

       主要看synchronized 鎖的是不是同一個對象,是一個對象,則下一個線程則需要等待上一個線程釋放對象鎖,(記住是對象鎖)

五、什么場景用?

        synchronized 雖然能保證線程安全,但是在并發場景下,會影響性能,比如在搶購場景下。還有加鎖的方法或者加鎖代碼塊是不是一個很耗時的流程,或者一個公共方法,很多業務邏輯都用到,這時候,并發環境下,基本行不通,不同的業務場景下不應該有干擾。所以盡量根據不同的場景和業務邏輯謹慎使用,也可以通過其他方式保證線程的安全,比如用并發包中的一些數據結構,或者ThreadLocal實現線程上下文變量一致性,防止其他程序對公共變量進行篡改。

六、擴展知識

1、很多人問,synchronized 和 實現Lock接口的對象都有加鎖的功能,在開發的時候如何選擇?

     《深入理解Java虛擬機》線程安全和鎖優化一章有簡單做介紹,synchronized 和ReentrantLock在JDK1.5 中單核,ReentrantLock比synchronized 的性能要好,多核CPU 下synchronized還是比ReentrantLock好,這樣可以看出synchronized 的性能并不差,所以在JDK1.6,JVM在synchronized 的優化,性能已經由于Lock,在一般的synchronized 能滿足需求的情況下會使用synchronized 。

2、那Lock又有哪些優勢呢?

      synchronized 是java 的原生鎖,而ReentrantLock是基于API的方式進行加鎖的,和一些鎖的其他操作。功能比synchronized 要強大,那就意味著用起來就靈活,可以實現很多synchronized 沒有的功能,例如:

1.等待過程中,可以直接中斷等待(如果一直沒有獲得鎖的話)

2.公平鎖:基于時間先后進行鎖獲取,不是synchronized 一樣無序競爭。

3.一個ReentrantLock對象可以綁定多個鎖對象,synchronized (Object)需要多個對象,而ReentrantLock只需多次調用newCondition()方法即可。

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

木里| 施秉县| 泾源县| 浠水县| 剑河县| 庆元县| 清涧县| 乌什县| 山阴县| 平武县| 曲松县| 疏勒县| 黔南| 通州区| 昭平县| 青海省| 镇平县| 巫山县| 陆川县| 诸城市| 汨罗市| 门源| 长汀县| 榆林市| 东明县| 澳门| 雷山县| 和田市| 吴桥县| 柯坪县| 娄底市| 珠海市| 鄂温| 凌云县| 凤凰县| 吉首市| 徐闻县| 连城县| 昭苏县| 临邑县| 安顺市|