[英]Java “static final” vs just “static” variable while locking
我一直在閱讀有關將靜態對象用作鎖的信息,最常見的示例如下所示:
public class MyClass1 {
private static final Object lock = new Object();
public MyClass1() {
//unsync
synchronized(lock) {
//sync
}
//unsync
}
}
我的問題是鎖必須是最終的嗎? 我知道最好將它設置為final,以確保沒有人混淆值,但是如果沒有final,它將起作用嗎?
如果不把這些變量final
,你可能會得到一個NullPointerException
中的構造函數MyClass1
,如果你創建的實例MyClass1
在不同的線程比,其中線狀物MyClass1
加載。
final
修飾符以沒有final
的方式保證安全發布lock
。
另外,如果不是final
,則可以更改它,從而導致您鎖定了錯誤的對象實例。
您可以在Java語言規范第17.5節(“最終字段語義”) (第17章(“線程和鎖”)中)中找到有關final
修飾符在安全發布方面提供的保證的更多信息。
當然,它將起作用-直到您重新分配它為止。 如果lock
不是最終的,則有人可以為其分配另一個值( lock = new Object()
)。 這就像更換門上的鎖:如果您仍然有舊鑰匙,將無法再使用該鎖。
將lock
final可以防止這種情況的發生,因此,這樣做總是一個好主意。
基本上,您必須確保一旦創建了鎖定對象,任何人都不會以任何方式弄亂它。 因此,您必須通過使用static final
將其設置為constant
。 So, by creating a constant we are making sure that our lock object is created as soon as the class is loaded and never modify that in application lifetime.
獎勵 :
另一種方法是使用static initializer
。 這非常適合您希望在多個語句中進行鎖定對象分配的情況。 以下是一個示例:
public class Test {
private static final Test lockObject;
static {
System.out.println("Hello");
lockObject = new Test();
}
public static void main(String[] args) {
synchronized (lockObject) {
//your code goes here
}
}
}
如果以不同的方式編寫,可能會更直觀:與此幾乎相同
public class MyClass {
static Lock myLock = new ReentrantLock();
public MyClass1() {
//unsync
myLock.lock();
//sync
myLock.unlock();
//unsync
}
}
與myLock
是否為final相同的結果。
如果不是final
,而是重新分配,則鎖定狀態將無關緊要。
我還是建議使用Lock
類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.