安全发布,论证传递
safe publication, argument passing
我有两个线程,每个线程都有自己的计数器:线程 A 有 counterA,线程 B 有 counterB。每个线程都必须使用两个计数器:线程 A 必须使用 counterA 和 counterB,线程 B 也必须同时使用两者。
我正在使用 AtomicInteger 并在两个线程之间共享计数器,我将它们作为参数传递给线程,每个线程将两个计数器存储在私有字段中。
// ...
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吗?
安全发布是必要的,因为对对象的引用不够安全,无法在线程之间共享对象。
在这种情况下如何实现安全发布?
提前致谢。
术语"safe publication"不适用于此。安全发布是关于在构造函数中创建的状态的发布。在您的示例中, AtomicInteger
对象是在调用构造函数之前创建的。
如果使用其他类型,这可能安全也可能不安全,具体取决于 counterA
和 counterB
变量是否以及如何发布。但是,使用作为 AtomicInteger
对象实现的计数器,您无需担心发布问题。它们是原子的/线程安全的,无论它们是如何发布的。唯一可能关注可能是实例变量状态的发布。如果不查看 class 的其余部分,我们无法判断是否发生了这种情况。例如:
- 变量是
final
还是volatile
?
- 如果它们是非易失性和非最终的,对它们的访问是否正确同步?
- 它们在调用
run()
后是否受限线程?
请注意,runnable 将在当前线程中实例化,而不是在调用 tA.start()
和 tB.start()
时(以及如果)创建的线程中实例化。当调用 start()
时,在当前线程的 start()
调用和新线程的 run()
调用之间有一个 happens-before。这意味着可以保证将变量安全发布到子线程本身。只需要将变量发布到其他线程即可。
我有两个线程,每个线程都有自己的计数器:线程 A 有 counterA,线程 B 有 counterB。每个线程都必须使用两个计数器:线程 A 必须使用 counterA 和 counterB,线程 B 也必须同时使用两者。 我正在使用 AtomicInteger 并在两个线程之间共享计数器,我将它们作为参数传递给线程,每个线程将两个计数器存储在私有字段中。
// ...
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吗? 安全发布是必要的,因为对对象的引用不够安全,无法在线程之间共享对象。 在这种情况下如何实现安全发布?
提前致谢。
术语"safe publication"不适用于此。安全发布是关于在构造函数中创建的状态的发布。在您的示例中, AtomicInteger
对象是在调用构造函数之前创建的。
如果使用其他类型,这可能安全也可能不安全,具体取决于 counterA
和 counterB
变量是否以及如何发布。但是,使用作为 AtomicInteger
对象实现的计数器,您无需担心发布问题。它们是原子的/线程安全的,无论它们是如何发布的。唯一可能关注可能是实例变量状态的发布。如果不查看 class 的其余部分,我们无法判断是否发生了这种情况。例如:
- 变量是
final
还是volatile
? - 如果它们是非易失性和非最终的,对它们的访问是否正确同步?
- 它们在调用
run()
后是否受限线程?
请注意,runnable 将在当前线程中实例化,而不是在调用 tA.start()
和 tB.start()
时(以及如果)创建的线程中实例化。当调用 start()
时,在当前线程的 start()
调用和新线程的 run()
调用之间有一个 happens-before。这意味着可以保证将变量安全发布到子线程本身。只需要将变量发布到其他线程即可。