python筆記:#001#python簡介
阿新 • • 發佈:2022-05-03
synchronized 關鍵字是鎖的一種實現
class X { // 修飾非靜態方法 // 當修飾非靜態方法的時候,鎖定的是當前例項物件 this synchronized void foo() { // 臨界區 } // 修飾靜態方法 // 當修飾靜態方法的時候,鎖定的是當前類的 Class 物件 synchronized static void bar() { // 臨界區 } // 修飾程式碼塊 Object obj = new Object(); void baz() { synchronized(obj) { // 臨界區 // 鎖定obj 物件 } } }
- 當修飾非靜態方法的時候,鎖定的是當前例項物件 this
- 當修飾靜態方法的時候,鎖定的是當前類的 Class 物件
- 當修飾程式碼塊的時候,鎖定的是傳入的物件
加鎖 lock() 和解鎖 unlock() 是被 Java 默默加上的,Java 編譯器會在 synchronized 修飾的方法或程式碼塊前後自動加上加鎖 lock() 和解鎖 unlock()
class SafeCalc { long value = 0L; synchronized long get() { return value; } synchronized void addOne() { value += 1; } }
把 value 改成靜態變數,把 addOne() 方法改成靜態方法
class SafeCalc {
static long value = 0L;
synchronized long get() {
return value;
}
synchronized static void addOne() {
value += 1;
}
}
改動後的程式碼是用兩個鎖保護一個資源。這個受保護的資源就是靜態變數 value,兩個鎖分別是 this 和 SafeCalc.class
由於臨界區 get() 和 addOne() 是用兩個鎖保護的,因此這兩個臨界區沒有互斥關係,臨界區 addOne() 對 value 的修改對臨界區 get() 也沒有可見性保證,這就會導致併發問題了
class SafeCalc {
long value = 0L;
long get() {
synchronized (new Object()) {
return value;
}
}
void addOne() {
synchronized (new Object()) {
value += 1;
}
}
}
可以用一把鎖來保護多個資源,但是不能用多把鎖來保護一個資源
用不同的鎖對受保護資源進行精細化管理,能夠提升效能。叫細粒度鎖
- 如果資源之間沒有關係,很好處理,每個資源一把鎖就可以了。
- 如果資源之間有關聯關係,就要選擇一個粒度更大的鎖,這個鎖應該能夠覆蓋所有相關的資源。