私は、3つのスレッドが1から10の順に番号を印刷しようとしているプログラムを持っています。私はCountDownLatch
を使ってカウントを保持しています。3つのスレッドを使って順番に番号を印刷する
しかし、プログラムはただ1
注印刷した後に停止します。私はAtomicInteger
代わりのInteger
を使用して働くことができることを承知していますが。しかし、私は現在のコードで問題を見つけるために探しています。
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();
}
}
}
}
}
主なプログラム:
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();
}
}
}
編集プログラム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();
}
}
}
}
}
は 'AtomicInteger'、それはのAtomicInteger静的せずに動作すると、プログラムを更新し、あなたの問題を解決することを願っています。どうして? – Anurag
@Anurag:答えを編集しました。違いは 'Integer'では' Integer'オブジェクト自体を置き換えますが、 'AtomicInteger'では' AtomicInteger'インスタンスのフィールドを変更します。どちらの場合でも 'final'修飾子を追加して何が起こるかを見てみてください。 – fabian
JDKの' AtomicInteger'ソースから、 'int'値を保持しています。これはfinalではありません。しかし、Integerの場合は、最終的なint値を保持します。 したがって、 'Integer'が' int'を持っていて最終的ではなく、揮発性であった場合、理論的には動作します。 これは何を意味していますか? – Anurag