[英]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.