锁定时Java“静态最终”与仅“静态”变量

问题描述 投票:0回答:4

我一直在阅读使用静态对象作为锁,最常见的例子是这样的:

public class MyClass1 {
  private static final Object lock = new Object();
  public MyClass1() {
    //unsync
    synchronized(lock) {
      //sync
    }
    //unsync
  }
}

我的问题是锁是否必须是最终的?我理解将它作为最终确定没有人会对价值感到困惑是好的,但它会在没有最终的情况下发挥作用吗?

java
4个回答
2
投票

当然,它会起作用 - 直到你重新分配它。如果lock不是最终的,那么有人可以为它指定另一个值(lock = new Object())。这就像更换门上的锁:如果你还有旧钥匙,你将无法再使用锁。

制作lock final会阻止这种情况发生,因此这样做总是一个好主意。


2
投票

如果你没有制作变量final,你可以在NullPointerException的构造函数中得到一个MyClass1,如果你在与加载MyClass1的线程不同的线程中创建MyClass1的实例。

final修饰符保证lock安全发布的方式没有final没有。

此外,如果它不是final,它可能会被更改,导致您锁定错误的对象实例。

您可以在第17章(“线程和锁定”)中找到有关final修饰符在Java Language Specification Section 17.5 ("Final Field semantics")中安全发布方面提供的保证的更多信息。


0
投票

基本上你必须确保一旦创建了锁定对象,没有人会以任何方式搞砸它。因此,你必须使用constant制作static finalSo, 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
        }
    }
}

0
投票

如果以不同的方式编写它可能更直观:它与此几乎相同

public class MyClass {
    static Lock myLock = new ReentrantLock();
    public MyClass1() {
        //unsync
        myLock.lock();
        //sync
        myLock.unlock();
        //unsync
    }
}

myLock最终与否的相同后果。

如果它不是final并被重新分配,则锁定状态将无关紧要。

无论如何,我建议使用Lock课程。

© www.soinside.com 2019 - 2024. All rights reserved.