物件鎖的變化

2021-08-31 05:35:27 字數 1759 閱讀 5428

synchronized 關鍵字鎖定物件。物件是在 synchronized **內部被鎖定的,這一點對此物件以及您對其物件引用所作的更改意味著什麼呢?對乙個物件作同步處理只鎖定該物件。但是,必須注意不要重新分配被鎖定物件的物件引用。那麼如果這樣做會發生什麼情況呢?請考慮下面這段**,它實現了乙個 stack:

class stack 

intarr[index] = val;

index++;

} }

public int pop()

} return 0;

} //...

}

這段**用陣列實現了乙個 stack。建立了乙個初始大小為 10 的陣列來容納整數值。此類實現了 push 和 pop 方法來模擬 stack 的使用。在 push 方法中,如果陣列中沒有更多的空間來容納壓入的值,則陣列被重新分配以建立更多的儲存空間。(故意沒有用 vector 來實現這個類。 vector 中不能儲存基本型別。) 

請注意,這段**是要由多個執行緒進行訪問的。push 和 pop 方法每次對該類的共享例項資料的訪問都是在 synchronized 塊內完成的。這樣就保證了多個執行緒不能併發訪問此陣列而生成不正確的結果。

這段**有乙個主要的缺點。它對整數陣列物件作了同步處理,而這個陣列被 stack 類的 intarr 所引用。當 push 方法重新分配此整數陣列時,這個缺點就會顯露出來。當這種情況發生時,物件引用 intarr 被重新指定為引用乙個新的、更大的整數陣列物件。請注意,這是在 push 方法的 synchronized 塊執行期間發生的。此塊針對 intarr 變數引用的物件進行了同步處理。因此,在這段**內鎖定的物件不再被使用。請考慮以下的事件序列:

1. 執行緒 1 呼叫 push 方法並獲得 intarr 物件的鎖。

2. 執行緒 1 被執行緒 2 搶先。

3. 執行緒 2 呼叫 pop 方法。此方法因試圖獲取當前執行緒 1 在 push 方法中持有的同乙個鎖而阻塞。

4. 執行緒 1 重新獲得控制並重新分配陣列。 intarr 變數現在引用乙個不同的變數。

5. push 方法退出並釋放它對原來的 intarr 物件的鎖。

6. 執行緒 1 再次呼叫 push 方法並獲得新 intarr 物件的鎖。

7. 執行緒 1 被執行緒 2 搶先。

8. 執行緒 2 獲得舊 intarr 物件的物件鎖並試圖訪問其記憶體。(因為鎖是鎖定物件的,不是鎖定物件的引用)

這個問題是因 push 方法重新分配被鎖定物件的物件引用而造成的。當某個物件被鎖定時,其他執行緒可能在同乙個物件鎖上被阻塞。如果將被鎖定物件的物件引用重新分配給另乙個物件,其他執行緒的掛起鎖則是針對**中已不再相關的物件的。

您可以這樣修正這段**,去掉對 intarr 變數的同步,而對 push 和 pop 方法進行同步。通過將 synchronized 關鍵字新增為方法修飾符即可實現這一點。正確的**如下所示:

class stack 

intarr[index]= val;

index++;

} public synchronized int pop()

throw new emptystackexception();

} }

這個修改更改了實際上獲取的鎖。獲取的鎖是針對為其呼叫方法的物件的,而不是鎖定 intarr 變數所引用的物件。因為獲取的鎖不再針對 intarr 所引用的物件,所以允許**重新指定 intarr 物件引用。

JS訪問動態變化的物件

對於乙個js物件,訪問的方法,例如 var obj 我們知道可以使用obj.name或者obj.age來訪問obj中的物件,但是有時候會遇到一種情況,就是物件中包含動態變化的物件,例如 var obj 如果此時我們想訪問obj中的 addresshome,正常是可以使用obj.addresshome...

類鎖和物件鎖的詳解

最近在面試中遇到很多關於多執行緒的問題,特別是鎖的應用,現在我就來說說類鎖和物件鎖。物件鎖 synchronized method 和類鎖 static sychronized method 的區別 物件鎖也叫例項鎖,對應synchronized關鍵字,當多個執行緒訪問多個例項時,它們互不干擾,每個...

java的物件鎖和類鎖

類鎖 在 中的方法上加了static和synchronized的鎖,或者synchronized class 物件鎖 在 中的方法上加了synchronized的鎖,或者synchronized this 的 段 方法鎖和私有鎖 都屬於物件鎖 私有鎖 在類內部宣告乙個私有屬性如private obj...