import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class Main implements Runnable {
private final CountDownLatch cdl1 = new CountDownLatch(NUM_THREADS);
private volatile int bar = 0;
private AtomicInteger count = new AtomicInteger(0);
private static final int NUM_THREADS = 25;
public static void main(String[] args) {
Main main = new Main();
for(int i = 0; i < NUM_THREADS; i++)
new Thread(main).start();
}
public void run() {
int i = count.incrementAndGet();
cdl1.countDown();
try {
cdl1.await();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
bar = i;
if(bar != i)
System.out.println("Bar not equal to i");
else
System.out.println("Bar equal to i");
}
}
それぞれThread
が run メソッドに入り、呼び出された から値を取得することによって、スレッドに限定された一意のint
変数を取得します。次に、それぞれが呼び出されるのを待ちます(最後のものがラッチに到達すると、すべてが解放されます)。ラッチが解放されると、各スレッドは、限定された値を共有されたに割り当てようとします。i
AtomicInteger
count
Thread
CountDownLatch
cdl1
Thread
Threads
i
volatile
int
bar
Thread
1つを除くすべてが「バーがiに等しくない」と出力することを期待しますが、すべてThread
が「バーがiに等しい」と出力します。ええと、wtf はvolatile
実際にそうしないとしますか?
それぞれがまったく同時にThread
の値を設定しようとするのは、意図的な意図です。bar
編集:
答えに照らして、コードを次のように変更しました。
...
bar = i;
try {
Thread.sleep(0);
} catch(InterruptedException e) {
e.printStackTrace();
}
...
変数の設定と読み取りの間に少しの時間が無駄になるようにするため。
これで、バーの同じ/異なる値で印刷が 50/50 になりました。