主要是Hashtable提供的elements()方法迭代产生的Enumeration类会发生线程安全
示例如下:
public static void main(String[] args) {
ThreadPoolExecutor threadPoolExecutor =
new ThreadPoolExecutor(5, 50, 1, TimeUnit.SECONDS, new LinkedBlockingDeque<>(100),
new ThreadPoolExecutor.CallerRunsPolicy());
Hashtable<Integer, Integer> hashtable = IntStream.range(0, 1000).boxed()
.collect(Collectors.toMap(o -> o, o -> o, (u, v) -> {
throw new IllegalStateException(String.format("Duplicate key %s", u));
}, Hashtable::new));
Enumeration<Integer> elements = hashtable.elements();
Set<Integer> result = new HashSet<>();
CompletableFuture[] completableFutures = IntStream.range(0, 2000)
.mapToObj(o -> CompletableFuture.runAsync(() -> {
if (elements.hasMoreElements()) {
Integer integer = elements.nextElement();
// 如果停一下效果更明显
/*try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
if (result.contains(integer)) {
throw new RuntimeException("数字重复了");
} else {
result.add(integer);
}
}
}, threadPoolExecutor).exceptionally(new Function<Throwable, Void>() {
@Override
public Void apply(Throwable throwable) {
System.out.println("发生线程安全问题:" + throwable.getMessage());
return null;
}
}))
.toArray(CompletableFuture[]::new);
CompletableFuture.allOf(completableFutures).join();
threadPoolExecutor.shutdown();
}