非最终字段是否也需要在构造函数中同步以确保线程安全?

时间:2019-05-04 10:24:09

标签: java

Java Concurrency In Practice的第69页(清单4.11)中,它们显示了以下类作为线程安全的示例:

@ThreadSafe
public class SafePoint {
  @GuardedBy("this") private int x, y;

  private SafePoint(int[] a) {
    this(a[0], a[1]);
  }

  public SafePoint(SafePoint p) {
    this(p.get());
  }

  public SafePoint(int x, int y) {
    this.x = x;
    this.y = y;
  }

  public synchronized int[] get() {
    return new int[]{x, y};
  }

  public synchronized void set(int x, int y) {
    this.x = x;
    this.y = y;
  }

  public static void main(String[] args) {
    SafePoint point = new SafePoint(1, 2);
    System.out.println(Arrays.toString(point.get()));

  }
}

请注意,构造函数SafePoint(int x, int y)是公共的,并且不使用常规监视器this设置非最终字段x和y。 在不使用通常用于监视这些字段的常规监视器的情况下,在构造函数中设置非最终字段是否被认为是线程安全的?如果是这样,那为什么呢?通常,我们需要使用同一监视器进行任何修改,以确保可见性。

我注意到该站点中该构造函数的代码不同,并且确实使用this作为监视器来设置这些字段:

public SafePoint(int x, int y) {
    this.set(x, y);
}

我想弄清楚这种区别是否是修饰性的或解决了此问题?

0 个答案:

没有答案