synchronized关键字原理
認(rèn)識synchronized
對于寫多線程程序的人來說,經(jīng)常碰到的就是并發(fā)問題,對于容易出現(xiàn)并發(fā)問題的地方價格synchronized基本上就搞定 了,如果說不考慮性能問題的話,這一操絕對能應(yīng)對百分之九十以上的情況,若對于性能方面有要求的話就需要額外的知識比如讀寫鎖等等。本文目的先了解透徹synchronized的基本原理。
Synchronized的基本使用
Synchronized的作用主要有三個:
(1)確保線程互斥的訪問同步代碼
(2)保證共享變量的修改能夠及時可見
(3)有效解決重排序問題。
從語法上講,Synchronized總共有三種用法:
(1)修飾普通方法
(2)修飾靜態(tài)方法
(3)修飾代碼塊
public class SynchronizedDemo {public void method() {synchronized (this) {System.out.println("Method 1 start");}} }對于上述方法我們很容易就知道是線程安全的,具體是怎么做的到的線程安全呢,對class通過javap編譯結(jié)果如下:
monitorenter
每個對象有一個監(jiān)視器鎖(monitor)。當(dāng)monitor被占用時就會處于鎖定狀態(tài),線程執(zhí)行monitorenter指令時嘗試獲取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
執(zhí)行monitorexit的線程必須是objectref所對應(yīng)的monitor的所有者。
指令執(zhí)行時,monitor的進(jìn)入數(shù)減1,如果減1后進(jìn)入數(shù)為0,那線程退出monitor,不再是這個monitor的所有者。其他被這個monitor阻塞的線程可以嘗試去獲取這個 monitor 的所有權(quán)。
通過這兩段描述,我們應(yīng)該能很清楚的看出Synchronized的實(shí)現(xiàn)原理,Synchronized的語義底層是通過一個monitor的對象來完成,其實(shí)wait/notify等方法也依賴于monitor對象,這就是為什么只有在同步的塊或者方法中才能調(diào)用wait/notify等方法,否則會拋出java.lang.IllegalMonitorStateException的異常的原因。
原理總結(jié)
每個對象都有一個內(nèi)部的鎖或者叫做是監(jiān)視器,稱之為monitor,當(dāng)一個方法加上synchronized關(guān)鍵字的時候,如果一個線程想執(zhí)行這個方法那么首先需要獲取這個對象的monirot權(quán)限,對應(yīng)到指令上面也就是需要獲取monitorenter 指令,如果一個對象獲取到這個指令之后,那么monitor的進(jìn)入數(shù)為1,當(dāng)其他線程再次獲取的時候發(fā)現(xiàn)這個對象的monitor對象被別的線程所占用,那么進(jìn)入阻塞狀態(tài),知道占用這個對象的線程執(zhí)行monitorexit,設(shè)置進(jìn)入數(shù)為0為止。
如果synchronized加在普通方法上,那么有效的范圍是多個線程執(zhí)行同一個對象的方法。通過上面的解釋應(yīng)該比較容易理解了,因?yàn)椴煌膶ο螳@取的是不同的monitor監(jiān)視器,自然也就不存在占用–等待的過程了。如果是加載static方法上那么需要獲取的就是這個對象所在class的Class對象,所以此時不管是幾個對象,對應(yīng)的都是同一個class對象,也就是說多個線程又存在對同一個monitor的占用—等待的過程了。所以說加載static上是對于整個類文件有效。
轉(zhuǎn)載于:https://www.cnblogs.com/yifanSJ/p/9221076.html
總結(jié)
以上是生活随笔為你收集整理的synchronized关键字原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【咸鱼教程】基于系统时间的计时器Date
- 下一篇: Java8 Time