Hello. Please help me with the following task:
Use the LongAccumulator class to calculate the maximum and minimum accumulated items.
It is understood that there should be several streams, and the type of generation of elements is arbitrary. Here is my code:
import java.util.Random; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.atomic.LongAccumulator; public class Main { public static LongAccumulator maxValue = new LongAccumulator(Math::max, Integer.MIN_VALUE); public static LongAccumulator minValue = new LongAccumulator(Math::min, Integer.MAX_VALUE); public static void main(String[] args){ Random random = new Random(); // Executor executor = Executors.newCachedThreadPool(); Executor executor = Executors.newFixedThreadPool(1); for (int i = 1; i <= 1000; i++) { int taskId = i; Runnable task = () -> { for (int k = 1; k <= 100_000; k++){ int value = random.nextInt(1_000_000); maxValue.accumulate(value); minValue.accumulate(value); } System.out.println(taskId + ": min " + minValue.get() + ": max " + maxValue.get()); }; executor.execute(task); } } } Everything works, but not as I expected. If all tasks are put into one thread (see the Executor executor = Executors.newFixedThreadPool(1); ) line, then everything works out more or less quickly. If instead of this line we substitute Executor executor = Executors.newCachedThreadPool(); , or put several threads: Executor executor = Executors.newFixedThreadPool(5); , the code works several times longer. Actually, the question is why this is happening and how to make it so that the division of tasks into threads does not increase the running time of the program, but reduces it.
UPD. According to the advice given in the comments, I changed the code as follows, and the program began to work faster in multi-threaded mode:
import java.util.Random; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.atomic.LongAccumulator; public class Main { public static LongAccumulator maxValue = new LongAccumulator(Math::max, Integer.MIN_VALUE); public static LongAccumulator minValue = new LongAccumulator(Math::min, Integer.MAX_VALUE); public static void main(String[] args){ Executor executor = Executors.newCachedThreadPool(); Runnable task; // вынес объявление из цикла ниже for (int i = 1; i <= 1000; i++) { Random random = new Random(); // для каждой задачи создаётся свой Random int taskId = i; task = () -> { for (int k = 1; k <= 100_000; k++){ int value = random.nextInt(1_000_000); maxValue.accumulate(value); minValue.accumulate(value); } System.out.println(taskId + ": min " + minValue.get() + ": max " + maxValue.get()); }; executor.execute(task); } } }