java - 为什么实践书中并发的 SafePoint 类标记为@ThreadSafe?

标签 java multithreading concurrency thread-safety

在《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]);

我相信有几种可能的结果:

  1. 申请没有完成
    否则
  2. 如果申请完成,我们可以看到
    一)0 0
    b) 0 1
    c) 1 0
    d) 1 1

我说得对吗?

如果为真,为什么作者将类标记为线程安全的?我认为线程安全类 - 无需复杂分析即可在并发应用程序中使用的类。

作者想表达什么?

附言

我读过 Private constructor to avoid race condition

...而且我的主题没有重复。

最佳答案

我同意 OP 的观点,该示例似乎违反了通常对 @ThreadSafe 保证的理解。不安全的发布竞赛非常真实,当然您可以在通过竞赛发布 SafePoint 时看到令人费解的行为。一些现实生活中的线程安全类在发布时仍然存在(String 是一个臭名昭著的例子),增加了困惑。

就 JCIP 的叙述而言,我手边没有纸质或电子副本,因此联系了 Doug Lea(主要作者之一),他说:

I think the part of confusion is in the JCIP text. I don't think @ThreadSafe covers publication races, or any other races that could be encountered during construction. Publication safety is treated separately.

Still, I can see how people could think otherwise. It is one of the reasons for us exploring always placing release fences in constructors.

Doug 谈论的最后一部分在 "All Fields Are Final" 中有简要描述。 ,包括动机、实验补丁和性能估计。

关于java - 为什么实践书中并发的 SafePoint 类标记为@ThreadSafe?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42364006/

相关文章:

java - 将 FutureTask 转换为 ScheduledFuture

java - 如何在网络浏览器中打开 pdf 文件?

java - 从套接字读取 http post 内容时出现问题,仅获取 header

multithreading - Dart是否会在多核环境中并行执行隔离?

Python 共享队列 - 2 个不同的线程

java - 迭代器和 ConcurrentModificationException

java - 高性能非阻塞有序消息处理程序

java - 如何在 Intellij 中远程调试作为 docker 容器运行的 java 应用程序

java - 为什么在单选按钮或复选框上应用时不显示错误消息

c# - C#/。NET ThreadException-创建窗口句柄时出错