首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java "static final“vs锁定时的"static”变量

Java "static final“vs锁定时的"static”变量
EN

Stack Overflow用户
提问于 2018-03-05 15:43:49
回答 4查看 69关注 0票数 0

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

代码语言:javascript
复制
public class MyClass1 {
  private static final Object lock = new Object();
  public MyClass1() {
    //unsync
    synchronized(lock) {
      //sync
    }
    //unsync
  }
}

我的问题是,锁定一定要是最终的吗?我知道把它作为final来保证没有人会篡改它的值是很好的,但是没有final它能工作吗?

EN

回答 4

Stack Overflow用户

发布于 2018-03-05 15:49:25

如果不将变量设置为final,并且在与加载NullPointerException的线程不同的线程中创建MyClass1的实例,则可能会在MyClass1的构造函数中获得MyClass1

final修饰符保证了lock的安全发布,这是没有final所不能做到的。

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

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

票数 2
EN

Stack Overflow用户

发布于 2018-03-05 15:50:12

当然,它会工作的--直到您重新分配它。如果lock不是最终的,有人可以给它赋另一个值(lock = new Object())。这就像更换门上的锁一样:如果你仍然有旧钥匙,你就不能再使用锁了。

lock设为final将防止这种情况发生,因此这样做总是一个好主意。

票数 2
EN

Stack Overflow用户

发布于 2018-03-05 16:05:16

基本上,您必须确保一旦创建了锁对象,就没有人会以任何方式搞乱它。因此,您必须让它成为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.

Bonus

做同样事情的另一种方法是使用static initializer。这非常适合您希望在多个语句中进行锁对象赋值的情况。下面是一个相同的示例:

代码语言:javascript
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49105590

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档