首页 > 解决方案 > 克服 Java 中的不当发布

问题描述

我在“Java 并发实践”一书中遇到了以下课程。作者指出,在下面的示例中,Holder 的状态可能是陈旧的,从而在调用 assertSanity 时导致 AssertionError。如何将下面的 Holder 类设为不可变来克服这个问题?

public class Holder{

  private int n;

  public Holder(int n) { this.n = n;}

  public void assertSanity() {
     if(n != n)
          throw new AssertionError(" this statement is false");

  }

}

//unsafe publication
public Holder holder;

public void initialize(){
     holder = new Holder(42);
}

标签: javajava.util.concurrentjava-threads

解决方案


要使Holder类不可变,只需更改

  private int n;

  private final int n;

如果您愿意,您还可以为该字段添加一个公共(非synchronized)getter 方法。Holder.n没有什么可以使用的私有字段没有什么意义。

(但要摆脱它,assertSanity因为它在世上没有用处。)

完成上述操作后,该字段Holder将是不可变的n,您不必担心该字段的不安全发布。


推荐阅读