java - 安全发布,论证传递

标签 java thread-safety safe-publication

我有两个线程,每个线程都有自己的计数器:线程A有counterA,线程B有counterB。每个线程必须使用两个计数器:线程 A 必须使用 counterA 和 counterB,线程 B 也必须使用两者。 我正在使用 AtomicInteger 并在两个线程之间共享计数器,我将它们作为参数传递给线程,并且每个线程将两个计数器存储在私有(private)字段中。

// ...
AtomicInteger counterA = new AtomicInteger(0);
AtomicInteger counterB = new AtomicInteger(0);

Thread tA = new Thread(new RunnableA(counterA, counterB)); 
Thread tB = new Thread(new RunnableB(counterA, counterB)); 

// ... in the constructor of RunnableA ...
RunnableA(AtomicInteger counterA, AtomicInteger counterB) {
    this.counterA = counterA;
    this.counterB = counterB;
} 

//...
// The same for RunnableB

这是safe publishing吗?两个计数器的? 安全发布是必要的,因为对对象的引用不够安全,无法在线程之间共享该对象。 这种情况下如何实现安全发布?

提前致谢。

最佳答案

“安全发布”一词不适用于此。安全发布是指在构造函数中创建的状态的发布。在您的示例中,AtomicInteger对象是在调用构造函数之前创建的。

如果使用其他类型,这可能安全也可能不安全,具体取决于 counterA 是否以及如何和counterB变量已发布。但是,计数器实现为 AtomicInteger对象,您无需担心发布。它们是原子/线程安全的,无论它们如何发布。唯一可能的问题可能是实例变量状态的发布。如果不观察类的其他同学,我们就无法判断这种情况是否会发生。例如:

  • 是变量finalvolatile
  • 如果它们是非 volatile 且非最终的,对它们的访问是否正确同步?
  • run() 之后它们是否受到线程限制叫做?

请注意,可运行对象将在当前线程中实例化,而不是在 tA.start() 时创建的线程中实例化。和tB.start()叫做。当start()被调用时,当前线程的 start() 之间有一个 happens-before调用和新线程的 run()称呼。这意味着可以保证将变量安全发布到子线程本身。所关心的只是将变量发布到其他线程。

关于java - 安全发布,论证传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40527899/

相关文章:

c# - 暂停和恢复线程的替代方法有哪些?

java - 将 ConcurrentHashMap 安全发布到类字段中

Java 多线程和安全发布

java - 启动 Grizzly Web 服务器的最佳方式是什么?

java - 从 Web url 检索完整页面源

java - 我怎样才能找到replace_all的正则表达式?

c++ - srand() + rand() 局部作用域

java - 将整个 where 子句传递给 native spring jpa @Query

C++ 线程安全映射

java - 在构造函数之外初始化的最终字段是否会在运行构造函数之前初始化?