在Java Concurrency in Practice一书中,您可以找到以下代码:
@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;
}
}
这标记为 @ThreadSafe
.
我很确定这个类不是线程安全的(如果我理解这个术语的话) .
例:
SafePoint racePublishedSafePoint; // field
// thread 1:
racePublishedSafePoint = new SafePoint(1,1);
// thread 2:
SafePoint sp;
while(true){
SafePoint sp = racePublishedSafePoint;
if(sp != null) break;
}
System.out.println(sp.get()[0]);
System.out.println(sp.get()[1]);
我相信有几种可能的结果:
-
应用程序未完成
其他 -
如果申请完成,我们可以看到
a)0 0
b)0 1
c)1 0
d)1 1
我对吗?
如果为true,为什么作者将该类标记为线程安全?我认为这个线程安全的类 - 可以在没有复杂分析的情况下用于并发应用程序 .
作者想说什么?
P.S.
我看过Private constructor to avoid race condition
......我的主题不重复 .
1 回答
我同意OP的观点,这个例子似乎违反了通常对
@ThreadSafe
保证的理解 . 不安全的出版比赛是非常真实的,当然,你可以通过比赛发布SafePoint
时看到令人费解的行为 . 一些现实生活中的线程安全类可以在有趣的出版物中存活(String
是一个臭名昭着的例子),这加剧了混乱 .就JCIP叙述而言,我没有纸质或电子副本,因此与Doug Lea(主要作者之一)联系,他说:
Doug正在讨论的最后一部分在_1429698中进行了简要描述,包括动机,实验补丁和性能估计 .