同時環境では、オブジェクトサンプルコードを安全にパブリッシュしません.
1434 ワード
package com.mm.concurrent;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestConcurrent {
public static void main(String[] args) throws InterruptedException {
final List<ValueOwner> list = new ArrayList<>(10000);
for(int i = 0; i < 10000; i++){
list.add(new ValueOwner());
}
CountDownLatch latch = new CountDownLatch(1);
CountDownLatch watchDog = new CountDownLatch(200);
ExecutorService es = Executors.newFixedThreadPool(200);
for(int i = 0; i < 200; i++){
es.execute(new Runnable() {
@Override
public void run() {
try {
latch.await();
for(ValueOwner vo : list){
vo.check();
}
watchDog.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
latch.countDown();
int n = 0;
for(ValueOwner vo : list){
vo.setValue(++n);
}
watchDog.await();
es.shutdown();
}
}
class ValueOwner {
private int value;
public ValueOwner() {
}
public void setValue(int value) {
this.value = value;
}
public void check() {
if (value != value) {
throw new RuntimeException();
}
}
}
解析:checkを呼び出すスレッドは、最初のvalueを取得したときに表示されるオブジェクト初期化の属性値value=0であり、2番目を読むときに主スレッドsetのvalue値を読み取ると、2つの不一致が異常を放出することが分かった.