我可以使用synchronized到最终字段吗?

时间:2012-07-13 20:36:33

标签: java final synchronize

考虑下面的代码,我想让它成为一个线程安全的类,这样它就永远不会得到奇数:

class Test {
  private int value = 0;
  private final Object lock;

  public void add() {
    synchronized (lock) {
      value++;
      value++;
    }
  }

  public int getValue() {
    synchronized (lock) {
      return value;
    }
  } 
}

我现在怀疑锁定字段,这被宣布为最终的,这有关系吗?或者它会打破线程的安全吗?

我认为如果未将lock字段声明为final,那么这应该是一个线程安全的类。如果这个结论有误,请指正,谢谢。

6 个答案:

答案 0 :(得分:9)

  

我现在怀疑锁定字段,它被宣布为最终的,这有关系吗?

是的,它被认为是锁定final字段对象的最佳做法。

如果您可以更改引用,则可以更改锁定的对象,从而破坏线程安全。

答案 1 :(得分:1)

应该没问题。甚至可能使它更安全,因为在执行期间不能简单地将其他东西分配给锁。

答案 2 :(得分:1)

答案 3 :(得分:1)

如果你想锁定一个实例,那么final是可以接受的。如果您想在类上锁定或放置互斥锁,请将变量设置为静态。

答案 4 :(得分:0)

在Java中,同步由锁定对象的某个隐藏字段完成。最后的意思是,REFERENCE是最终的,而不是对象本身。示例:

final Bar bar = new Bar(); //bar hase property lock
bar.lock = XYZ; //will work, object is not FINAL
bar = new Bar(); //fail, the reference is FINAL

答案 5 :(得分:0)

当您尝试同步多个线程时,必须根据相同的对象引用/实例对它们进行同步。这可以确保它们根据相同的数据同时进行同步。

希望这有点意义;你只需要根据最终变量而不是动态变量进行同步。

  

如果方法修改静态字段,则必须同步访问权限   此字段,即使该方法通常仅由单个使用   线。客户端无法执行外部操作   这种方法同步因为无法保证   不相关的客户也会这样做,see