Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ParallelStream with Maps

I want to read values from complex map and execute one function in parallel way. For that I am using ForkJoinPool from Java 8.

Issue I am facing here is, for few values, function is executed twice. Initially I thought, Hashmap is not thread safe so I have tried to use HashTable, but its the same...

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();
like image 927
ash-rocks Avatar asked Apr 16 '26 08:04

ash-rocks


1 Answers

For parallel stream the thread-safety of the input collection is unnecessary as long as it's not updated. On the other way, Hashtable.entrySet() is a very bad source for parallel stream as Hashtable does not have custom spliterator implementation. Using HashMap is much better. Nevertheless, the provided code everything should work correctly, either with HashMap or with Hashtable (though much less efficient with Hashtable). I suspect that the problem is inside not shown here cakeService.updateCakeOrderStatusAndPrice which is likely to be not thread-safe.

like image 97
Tagir Valeev Avatar answered Apr 19 '26 08:04

Tagir Valeev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!