私はJavaスレッドを騙しています。私はいくつかのスレッドを作成して実行する小さなプログラムを書いています。各スレッドでは、値が複数回インクリメントされます。 ThreadLocalクラスを使用して、リソースの競合がないようにしました。Javaの並行性:奇妙な出力
出典:
MyTask 5, Value 100
MyTask 5, Value 100
MyTask 5, Value 100
MyTask 5, Value 100
MyTask 5, Value 100
私が見に期待するものはどれ:
class MyValueHolder {
public static ThreadLocal<Integer> value = new ThreadLocal<Integer>()
{
protected Integer initialValue() {
return 0;
}
};
public static void increment() {
value.set(value.get() + 1);
}
public static Integer get() {
return value.get();
}
}
class MyTask implements Runnable {
public static int counter;
public MyTask() {
counter++;
}
public void run() {
for(int i = 0; i < 100; i++) {
MyValueHolder.increment();
}
System.out.println("MyTask " + counter + ", Value " + MyValueHolder.get());
}
}
public class Main {
public static void main(String[] args) {
ExecutorService es = Executors.newCachedThreadPool();
for(int i = 0; i < 5; i++) {
es.execute(new MyTask());
}
es.shutdownNow();
}
}
終了後出力はこの時間のほとんどです。
はしかし、時々私はこのような何かを得る:
MyTask 2, Value 100
MyTask 4, Value 200
MyTask 5, Value 300
MyTask 5, Value 100
MyTask 5, Value 100
さて、これは紛らわしいです。各タスクが全く同じことをしても、値が異なるのはなぜですか?
スレッドが実行される順序は、開始された順序であることが保証されていません**。スレッドを特定の順序で実行する必要がある場合は、 'wait' /' notify'または['CountDownLatch'](https://docs.oracle.com/javase/7/docs/api/java/util/)を使用してください。同時/ CountDownLatch.html)。 – Majora320