Java8 number of threads

I am curious how to sum several variables in a java8 thread.

Integer wCPU = 0; Double wnetwork = 0.0; Double wMem = 0.0; this.slaContractList.forEach(sla -> { wCPU += sla.getNumberOfCPUs(); wnetwork += sla.getNetworkBandwith(); wMem += sla.getMemory(); }); 

However, this does not compile, since the variable in the lambda expression must be final.

+5
source share
4 answers

Assuming slaContractList is a list of SlaContract objects and it has a SlaContract(numberOfCPUs, networkBandwith, memory) constructor SlaContract(numberOfCPUs, networkBandwith, memory) , you can:

 SlaContract sumContract = slaContractList.stream() .reduce(new SlaContract(0, 0.0, 0.0), (sla1, sla2) -> { return new SlaContract(sla1.getNumberOfCPUs() + sla2.getNumberOfCPUs(), sla1.getworkBandwith() + sla2.getworkBandwith(), sla1.getMemory() + sla2.getMemory()); }); Double wnetwork = sumContract.getworkBandwith(); Double wMem = sumContract.getMemory(); Integer wCPU = sumContract.getNumberOfCPUs(); 

This is the same solution, but for a simple class:

 Point sumPoint = pointsList.stream() .reduce(new Point(0, 0), (p1, p2) -> { return new Point(p1.x + p2.x, p1.y + p2.y); }); 
+7
source

Try using Stream.reduce and Stream.sum :

 Double wnetwork = slaContractList.stream() .mapToDouble(sla -> sla.getNetworkBandwith()) .sum(); Double wMem = slaContractList.stream() .mapToDouble(sla -> sla.getMemory()) .sum(); Integer wCPU = slaContractList.stream() .mapToInt(sla -> sla.getNumberOfCPUs()) .sum(); 

See https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html

The advantage of using a stream is the option of using parallelStream() instead of stream() . In some situations, it may be more effective than a simple cycle.

+6
source

I would make it easy to hack like this:

  Integer[] wCPU = new Integer[1]; Double[] wnetwork = new Double[1]; Double[] wMem = new Double[1]; this.slaContractList.forEach(sla -> { wCPU[0] += sla.getNumberOfCPUs(); wnetwork[0] += sla.getNetworkBandwith(); wMem[0] += sla.getMemory(); }); 

It is not necessary to have the final keyword for both, as they introduced an effective final concept in Java 8. This means that you nominated only once.

+2
source

To make the sum, I would use the operation of summing the flows, as in Łukasz's answer, but for a more general solution to solve the "final problem" you can use the java.util.concurrent.atomic classes. It is intended for use in a stream and is thread safe, therefore it can be used in parallel flow.

 AtomicInteger wCPU = new AtomicInteger(); DoubleAccumulator wnetwork = new DoubleAccumulator(Double::sum,0.d); DoubleAccumulator wMem = new DoubleAccumulator(Double::sum,0.d); this.slaContractList.forEach(sla -> { wCPU.addAndGet(sla.getNumberOfCPUs()); wnetwork.accumulate(sla.getNetworkBandwith()); wMem.accumulate(sla.getMemory()); }); 

Now you see that there are 2 types of implementation: Battery and Atomic, the choice between these 2 is another question:

java 8: do LongAdder and LongAccumulator AtomicLong prefer?

+2
source

Source: https://habr.com/ru/post/1259648/


All Articles