我一直在阅读使用静态对象作为锁,最常见的例子是:
public class MyClass1 {
private static final Object lock = new Object();
public MyClass1() {
//unsync
synchronized(lock) {
//sync
}
//unsync
}
}
我的问题是锁是否必须是最终的?我理解将它作为最终确定没有人会对价值感到困惑是好的,但它会在没有最终的情况下发挥作用吗?
答案 0 :(得分:2)
如果您不创建变量NullPointerException
,如果您在不同的线程中创建MyClass1
的实例,则可能会在MyClass1
的构造函数中获得MyClass1
加载final
的线程。
lock
修饰符可确保以final
没有final
的方式安全发布final
。
此外,如果它不是{{1}},它可能会被更改,导致您锁定错误的对象实例。
您可以在Java Language Specification Section 17.5 ("Final Field semantics")中找到有关{{1}}修饰符在安全发布方面提供的保证的更多信息,第17章(“主题和锁定”)。
答案 1 :(得分:2)
当然,它会起作用 - 直到你重新分配它。如果lock
不是最终版,则有人可以为其指定另一个值(lock = new Object()
)。这就像更换门上的锁一样:如果你还有旧钥匙,你就不能再使用锁了。
制作lock
最终版本可以防止这种情况发生,所以这样做总是一个好主意。
答案 2 :(得分:0)
基本上你必须确保一旦锁定对象被创建,没有人会以任何方式搞砸它。因此,您必须使用constant
将其设为static final
。 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
}
}
}
答案 3 :(得分:0)
如果用不同的方式编写它可能更直观:它与此
几乎相同public class MyClass {
static Lock myLock = new ReentrantLock();
public MyClass1() {
//unsync
myLock.lock();
//sync
myLock.unlock();
//unsync
}
}
与myLock
最终决定的结果相同。
如果它不是final
并被重新分配,则锁定状态将无关紧要。
无论如何,我建议使用Lock
课程。