JCIP SafePoint - 它真的是线程安全的吗?

时间:2017-10-19 10:03:50

标签: java multithreading

在Brian Goetz等人的Java Concurrency in Practice中,有以下示例(列出4.11缩短版)。

public class SafePoint {
private int x, y;
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;
}

}

它真的是线程安全的吗? x和y既不是volatile也不是final,并且它们设置时没有锁定,这意味着调用get()的另一个线程可能会看到过时的值(零)。我在这里想念一下吗?

1 个答案:

答案 0 :(得分:3)

  

它真的是线程安全的吗?

  

x和y既不是易变的也不是最终的,

正确,但......

  

并且在没有锁定的情况下设置它们

不正确的。 get和set方法是synchronized方法,这意味着它们隐式锁定并在this上同步。

实际上......有一点需要注意。在创建SafePoint实例和某个其他线程上的(第一个)getset调用之间,之前也必须发生。如果没有,那么getset可能会看到xy的默认值,而不是传递给构造函数的值。

Goetz等人在Java Concurrency in Practice的下一页中介绍了这一点......尽管他们使用比 hb 关系更高级别的推理。在清单4.12中,他们使用ConcurrentHashMap来确保SafePoint 安全发布