日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

Java并发篇_synchronized

發(fā)布時(shí)間:2025/3/8 java 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java并发篇_synchronized 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

synchronized是Java語(yǔ)言的關(guān)鍵字,當(dāng)它用來修飾一個(gè)方法或者一個(gè)代碼塊的時(shí)候,能夠保證在同一時(shí)刻最多只有一個(gè)線程執(zhí)行該段代碼。本文給大家介紹java中的用法。

一、為什么要使用synchronized

在并發(fā)編程中存在線程安全問題,主要原因有:

1.存在共享數(shù)據(jù)

2.多線程共同操作共享數(shù)據(jù)。

關(guān)鍵字synchronized可以保證在同一時(shí)刻,只有一個(gè)線程可以執(zhí)行某個(gè)方法或某個(gè)代碼塊,同時(shí)synchronized可以保證一個(gè)線程的變化可見(可見性),即可以代替volatile。

synchronized可以保證方法或者代碼塊在運(yùn)行時(shí),同一時(shí)刻只有一個(gè)方法可以進(jìn)入到臨界區(qū),同時(shí)它還可以保證共享變量的內(nèi)存可見性

二、synchronized的用法

synchronized可以修飾靜態(tài)方法、成員函數(shù),同時(shí)還可以直接定義代碼塊,但是歸根結(jié)底它上鎖的資源只有兩類:一個(gè)是對(duì)象,一個(gè)是

  • 修飾普通方法(實(shí)例方法),鎖是當(dāng)前實(shí)例對(duì)象 ,進(jìn)入同步代碼前要獲得當(dāng)前實(shí)例的鎖
  • 修飾靜態(tài)方法,鎖是當(dāng)前類的class對(duì)象 ,進(jìn)入同步代碼前要獲得當(dāng)前類對(duì)象的鎖
  • 修飾方法塊,鎖是括號(hào)里面的對(duì)象,對(duì)給定對(duì)象加鎖,進(jìn)入同步代碼庫(kù)前要獲得給定對(duì)象的鎖。
  • 三、實(shí)現(xiàn)原理

    我們先通過反編譯下面的代碼來看看Synchronized是如何實(shí)現(xiàn)對(duì)代碼塊進(jìn)行同步的:

    package com.paddx.test.concurrent;public class SynchronizedDemo {public void method() {synchronized (this) {System.out.println("Method 1 start");}}}

    反編譯結(jié)果:

    關(guān)于這兩條指令的作用,我們直接參考JVM規(guī)范中描述:

    monitorenter :

    Each object is associated with a monitor. A monitor is locked if and only if it has an owner. The thread that executes monitorenter attempts to gain ownership of the monitor associated with objectref, as follows:
    ? If the entry count of the monitor associated with objectref is zero, the thread enters the monitor and sets its entry count to one. The thread is then the owner of the monitor.
    ? If the thread already owns the monitor associated with objectref, it reenters the monitor, incrementing its entry count.
    ? If another thread already owns the monitor associated with objectref, the thread blocks until the monitor’s entry count is zero, then tries again to gain ownership.

    這段話的大概意思為:

    每個(gè)對(duì)象有一個(gè)監(jiān)視器鎖(monitor)。當(dāng)monitor被占用時(shí)就會(huì)處于鎖定狀態(tài),線程執(zhí)行monitorenter指令時(shí)嘗試獲取monitor的所有權(quán),過程如下:

    1、如果monitor的進(jìn)入數(shù)為0,則該線程進(jìn)入monitor,然后將進(jìn)入數(shù)設(shè)置為1,該線程即為monitor的所有者。

    2、如果線程已經(jīng)占有該monitor,只是重新進(jìn)入,則進(jìn)入monitor的進(jìn)入數(shù)加1.

    3.如果其他線程已經(jīng)占用了monitor,則該線程進(jìn)入阻塞狀態(tài),直到monitor的進(jìn)入數(shù)為0,再重新嘗試獲取monitor的所有權(quán)。

    monitorexit:

    The thread that executes monitorexit must be the owner of the monitor associated with the instance referenced by objectref.
    The thread decrements the entry count of the monitor associated with objectref. If as a result the value of the entry count is zero, the thread exits the monitor and is no longer its owner. Other threads that are blocking to enter the monitor are allowed to attempt to do so.

    這段話的大概意思為:

    執(zhí)行monitorexit的線程必須是objectref所對(duì)應(yīng)的monitor的所有者。

    指令執(zhí)行時(shí),monitor的進(jìn)入數(shù)減1,如果減1后進(jìn)入數(shù)為0,那線程退出monitor,不再是這個(gè)monitor的所有者。其他被這個(gè)monitor阻塞的線程可以嘗試去獲取這個(gè) monitor 的所有權(quán)。

    通過這兩段描述,我們應(yīng)該能很清楚的看出Synchronized的實(shí)現(xiàn)原理,Synchronized的語(yǔ)義底層是通過一個(gè)monitor的對(duì)象來完成,其實(shí)wait/notify等方法也依賴于monitor對(duì)象,這就是為什么只有在同步的塊或者方法中才能調(diào)用wait/notify等方法,否則會(huì)拋出java.lang.IllegalMonitorStateException的異常的原因。

    我們?cè)賮砜匆幌峦椒椒ǖ姆淳幾g結(jié)果:

    源代碼:

    1 package com.paddx.test.concurrent; 2 3 public class SynchronizedMethod { 4 public synchronized void method() { 5 System.out.println("Hello World!"); 6 } 7 }

    反編譯結(jié)果:

    從反編譯的結(jié)果來看,方法的同步并沒有通過指令monitorenter和monitorexit來完成(理論上其實(shí)也可以通過這兩條指令來實(shí)現(xiàn)),不過相對(duì)于普通方法,其常量池中多了ACC_SYNCHRONIZED標(biāo)示符。JVM就是根據(jù)該標(biāo)示符來實(shí)現(xiàn)方法的同步的:當(dāng)方法調(diào)用時(shí),調(diào)用指令將會(huì)檢查方法的 ACC_SYNCHRONIZED 訪問標(biāo)志是否被設(shè)置,如果設(shè)置了,執(zhí)行線程將先獲取monitor,獲取成功之后才能執(zhí)行方法體,方法執(zhí)行完后再釋放monitor。在方法執(zhí)行期間,其他任何線程都無法再獲得同一個(gè)monitor對(duì)象。 其實(shí)本質(zhì)上沒有區(qū)別,只是方法的同步是一種隱式的方式來實(shí)現(xiàn),無需通過字節(jié)碼來完成。

    四、總結(jié)

    Synchronized是Java并發(fā)編程中最常用的用于保證線程安全的方式,其使用相對(duì)也比較簡(jiǎn)單。但是如果能夠深入了解其原理,對(duì)監(jiān)視器鎖等底層知識(shí)有所了解,一方面可以幫助我們正確的使用Synchronized關(guān)鍵字,另一方面也能夠幫助我們更好的理解并發(fā)編程機(jī)制,有助我們?cè)诓煌那闆r下選擇更優(yōu)的并發(fā)策略來完成任務(wù)。

    總結(jié)

    以上是生活随笔為你收集整理的Java并发篇_synchronized的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。