繁体   English   中英

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

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM