我想从复杂的地图中读取值并以并行方式执行一个函数。为此,我使用Java 8中的ForkJoinPool。
我面临的问题是,对于少数值,函数执行两次。 最初我认为,Hashmap不是线程安全的,所以我试图使用HashTable,但它一样......
final Map<CakeOrder, List<CakeOrderDetails>> cakeOrderMap = cakeUpdatesQueueItemDao.getCakeOrdersByStatus(EItemStatus.OPENED, country.getDbTableSuffix(), true);
final Map<CakeOrder, List<CakeOrderDetails>> cakeOrderTableMap = new Hashtable<>();
cakeOrderMap.forEach((k, v) -> cakeOrderTableMap.put(k, v));
final ForkJoinPool pool = new ForkJoinPool(20);
pool.submit(() -> cakeOrderTableMap.entrySet()
.stream()
.parallel()
.forEach(entry -> cakeService.updateCakeOrderStatusAndPrice(entry.getKey(), entry.getValue()))).invoke();
答案 0 :(得分:2)
对于并行流,输入集合的线程安全性是不必要的,只要它没有更新。另一方面,minDate: 3
是并行流的非常糟糕的来源,因为Hashtable.entrySet()
没有自定义spliterator实现。使用Hashtable
要好得多。尽管如此,提供的代码一切都应该正常工作,使用HashMap
或HashMap
(尽管Hashtable
效率低得多)。我怀疑问题是在Hashtable
这里没有显示,这可能不是线程安全的。