import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorTest {
public static void main(final String[] args) throws InterruptedException {
final ExecutorService executor = Executors.newFixedThreadPool(10);
final HashMap<Object, Object> map = new HashMap<Object, Object>();
final Collection<Callable<Object>> actions = new ArrayList<Callable<Object>>();
int i = 0;
while (i++ < 1000) {
final Object o = new Object();
actions.add(new Callable<Object>() {
public Object call() throws Exception {
map.put(o, o);
return null;
}
});
actions.add(new Callable<Object>() {
public Object call() throws Exception {
map.put(new Object(), o);
return null;
}
});
actions.add(new Callable<Object>() {
public Object call() throws Exception {
for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {
iterator.next();
}
return null;
}
});
}
executor.invokeAll(actions);
System.exit(0);
}
}
那么为什么会发生这种情况呢?或者更好的问题是——我该如何编写一个测试来确保自定义抽象映射的实现是线程安全的?(某些实现具有多个映射,另一些委托给缓存实现等)一些背景:这在Windows上的Java 1.6.0_04和1.6.0_07下发生。我知道问题来自sun.misc.Unsafe.park():我可以在我的Core2 Duo 2.4Ghz笔记本电脑上重现这个问题,但在调试模式下不会出现;我可以在我的Core2 Quad工作电脑上进行调试,但我已经通过RDP挂起了它,所以直到明天才能获得堆栈跟踪。大多数下面的答案都是关于HashMap的非线程安全性,但我在HashMap中找不到锁定的线程——所有的线程都在ExecutionService代码(和Unsafe.park())中。我将在明天仔细检查线程。所有这些都是因为自定义的抽象Map实现不是线程安全的,所以我开始确保所有实现都是线程安全的。实质上,我想确保我对ConcurrentHashMap等的理解与我所期望的完全相同,但发现ExecutionService奇怪地缺乏……