Ich habe zwei Threads, jeder hat seinen eigenen Zähler: Thread A hat counterA, Thread B hat counterB. Jeder Thread muss beide Counter verwenden: Thread A muss counterA und counterB verwenden, auch Thread B muss beides verwenden. Ich verwende AtomicInteger und teile die Zähler zwischen den beiden Threads, die ich ihnen als Argumente an die Threads übergebe und jeder Thread speichert die beiden Zähler in privaten Feldern.sichere Veröffentlichung, Argument übergeben
// ...
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
Ist das ein safe publishing der beiden Zähler? Safe-Publishing ist erforderlich, da eine Referenz auf ein Objekt nicht sicher genug ist, um das Objekt zwischen Threads zu teilen. Wie kann ich in diesem Fall eine sichere Veröffentlichung erreichen?
Vielen Dank im Voraus.
"Ich kann nicht sofort sehen, wie das sein könnte" - wenn auf die Zähler außerhalb von neu erstellten Threads als Instanzvariablen der Runnables zugegriffen wird. Die im Konstruktor initialisierten Werte sind vor dem Zugriff nicht garantiert sichtbar, es sei denn, es wird mindestens eine der Instanzvariablen final deklariert, siehe https://shipilev.net/blog/2014/safe-public-construction/ –
Nun ja ... aber wie kann auf diese Variablen mit * ally * zugegriffen werden, bevor der Konstruktor zurückkehrt? Sehen Sie sich den Code für den Konstruktor an. (Ich weiß, was sichere Veröffentlichung bedeutet, und "final" ist nur ein Weg, um es zu erreichen.) –
"Wenn start() aufgerufen wird, gibt es ein passiert-vorher zwischen dem Aufruf des aktuellen Threads() und dem neuen Thread ausgeführt() call. Dies bedeutet, dass eine sichere Veröffentlichung der Variablen für den untergeordneten Thread selbst gewährleistet ist. " Dies ist ein Punkt, den ich nützlich finde. Zum Beispiel muss man die "Argumentvariablen" (this.counterA, this.counterB) nicht als endgültig in Runnable, even deklarieren - obwohl Runnable im Hauptthread erstellt wird und später auf diese Argumentvariablen im Thread, der erstellt wird. –