5

直接从 Java 并发实践中得出:

@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;
  }
}

上面是一个线程安全的类:因为它的设置器是同步的。我也理解为什么 getter 不单独返回 x / y 而是返回一个数组。我有 2 个问题。为什么 ?

  1. private SafePoint(int[] a)
  2. public SafePoint(SafePoint p) { this(p.get()); }代替this(p.x,p.y);
4

1 回答 1

9

因为调用this(p.x, p.y)不是原子的。换句话说,想象以下线程交错:

  • 线程1:read p.x
  • 线程2:p.set(otherX, otherY);
  • Thread1:read p.y并调用this(p.x, p.y);

x 和 y 现在来自两个不同的点,并且可能不一致。

另一方面,p.get()以原子方式读取 x 和 y(它是synchronized),因此保证数组中的 x 和 y 来自同一点。

于 2012-12-20T10:27:52.450 回答