2016-08-04 19 views
-2
final BigDecimal couponlessAmount = orderItems.stream() 
      .filter(item -> !item.getIsUseCoupon()) 
      .map(item -> item.getTotalAmount().subtract(item.getReduceProductAmount())) 
      .reduce(BigDecimal.ZERO, BigDecimal::add); 

etwas bewirkt, dass die java.util.ConcurrentModificationExceptionjava8 stream map reduzieren verursachen die ConcurrentModificationException, warum?

java.util.ConcurrentModificationException 
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1380) ~[?:1.8.0_77] 
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[?:1.8.0_77] 
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[?:1.8.0_77] 
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[?:1.8.0_77] 
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:1.8.0_77] 
    at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:474) ~[?:1.8.0_77] 
    at com.yijiupi.himalaya.ordercompute.provider.domain.component.computer.CouponUseLimitComputer.getMaxUseAmount(CouponUseLimitComputer.java:103) ~[classes/:?] 
+0

manchmal, nicht jedes Mal, ich denke, es ist ein Bug von JDK, vielleicht JIT – komite

Antwort

0

Es ist unwahrscheinlich, JDK/JIT Bug sein. Wie üblich mit ConcurrentModificationException ist es ein Zeichen, dass Ihre orderItems gleichzeitig von einem anderen Thread geändert wird. Sie sollten ArrayList nicht gleichzeitig verwenden, ohne eine ordnungsgemäße externe Synchronisierung bereitzustellen. Beachten Sie, dass das Umbrechen von ArrayList in hier nicht ausreicht, da es die Durchquerungen nicht synchronisiert. Als Alternative (wenn Änderungen selten sind) verwenden Sie CopyOnWriteArrayList.