Ich habe ein Programm, wo 3 Threads versuchen, Zahlen in der Reihenfolge von 1 bis 10 zu drucken. Ich verwende eine CountDownLatch
, um eine Zählung zu behalten.Drucken von Zahlen in Folge mit 3 Threads
Aber das Programm stoppt kurz nach 1.
Hinweis Druck: Ich bin mir bewusst, dass AtomicInteger
statt Integer
mit arbeiten können. Aber ich suche das Problem im aktuellen Code.
public class Worker implements Runnable {
private int id;
private volatile Integer count;
private CountDownLatch latch;
public Worker(int id, Integer count, CountDownLatch latch) {
this.id = id;
this.count = count;
this.latch = latch;
}
@Override
public void run() {
while (count <= 10) {
synchronized (latch) {
if (count % 3 == id) {
System.out.println("Thread: " + id + ":" + count);
count++;
latch.countDown();
}
}
}
}
}
Hauptprogramm:
public class ThreadSequence {
private static CountDownLatch latch = new CountDownLatch(10);
private volatile static Integer count = 0;
public static void main(String[] args) {
Thread t1 = new Thread(new Worker(0, count, latch));
Thread t2 = new Thread(new Worker(1, count, latch));
Thread t3 = new Thread(new Worker(2, count, latch));
t1.start();
t2.start();
t3.start();
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Herausgegeben Programm mit AtomicInteger
:
public class ThreadSequence {
private static AtomicInteger atomicInteger = new AtomicInteger(1);
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new WorkerThread(0, atomicInteger));
Thread t2 = new Thread(new WorkerThread(1, atomicInteger));
Thread t3 = new Thread(new WorkerThread(2, atomicInteger));
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
System.out.println("Done with main");
}
}
public class WorkerThread implements Runnable {
private int id;
private AtomicInteger atomicInteger;
public WorkerThread(int id, AtomicInteger atomicInteger) {
this.id = id;
this.atomicInteger = atomicInteger;
}
@Override
public void run() {
while (atomicInteger.get() < 10) {
synchronized (atomicInteger) {
if (atomicInteger.get() % 3 == id) {
System.out.println("Thread:" + id + " = " + atomicInteger);
atomicInteger.incrementAndGet();
}
}
}
}
}
das Programm mit 'AtomicInteger' aktualisiert lösen wird und es funktioniert, ohne statische Atomicinteger . Warum? – Anurag
@Anurag: Bearbeitete die Antwort.Der Unterschied ist: mit 'Integer' ersetzen Sie das 'Integer'-Objekt selbst, aber mit' AtomicInteger' modifizieren Sie ein Feld der 'AtomicInteger'-Instanz. Versuchen Sie, in beiden Fällen den 'final'-Modifizierer hinzuzufügen und zu sehen, was passiert ... – fabian
Aus der JDK-Quelle von' AtomicInteger' sehe ich, dass es einen 'int'-Wert enthält, der NICHT endgültig ist. Aber im Falle von "Integer" enthält es einen "int" -Wert, der endgültig ist. Also, falls 'Integer' ein' int' hatte, das nicht final und flüchtig war, würde es theoretisch funktionieren. Das ist, was du meintest? – Anurag