I have two threads, each has its own counter: thread A has counterA, thread B has counterB. Each thread has to use both counters: thread A has to use counterA and counterB, also thread B has to use both. I am using AtomicInteger and to share the counters between the two threads I am passing them as arguments to the threads and each thread stores the two counters in private fields.
// ...
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
Is this a safe publishing of the two counters? Safe-publishing is necessary because a reference to an object is not safe enough to share the object between threads. How can I achieve safe-publishing in this case?
Thanks in advance.
The term "safe publication" is not applicable to this. Safe publication is about the publication of state that is created in the constructor. In your example, the AtomicInteger
objects were created before the constructor was called.
If some other type was used, this may or may not be safe depending on whether and how the counterA
and counterB
variables are published. However, with with counters implemented as AtomicInteger
objects, you don't need to worry about publication. They are atomic / thread-safe, irrespective how they are published. The only possible concern might be the publication of the state of the instance variables. We cannot tell whether that occurs without looking at the rest of the class. For example:
final
or volatile
?run()
is called? Note that the runnables will be instantiated in the current thread, not in the threads that are created when (and if) tA.start()
and tB.start()
are called. When start()
is called, there is a happens-before between the current thread's start()
call and the new thread's run()
call. This means that safe publication of the variables to the child thread itself is guaranteed. It is only publication of the variables to other threads that is of concern.