void (ExecutorService executor, Set<? super Thread> threadUsed, Semaphore threadReady, int L, IntConsumer index) { assert L % 4 == 0; threadUsed.clear(); threadReady.down();threadReady.down();threadReady.down();threadReady.down(); List<? extends Future<?>> futures = IntStream.range(0, 4).mapToObj(chunk -> executor.submit(() -> { threadUsed.add(Thread.currentThread()); threadReady.up(); threadReady.waitFor(); for (int i = L / 4 * chunk; i < L / 4 * chunk + L / 4; i++) { index.accept(i); } })).toList(); try { ConcurrencyUtil.getAll(futures); } catch (Exception e) { throw new RuntimeException(e); } assertTrue(threadReady.isUp()); assertEquals(4, threadUsed.size(), threadUsed.size() + " :\n" + StringUtil.join(threadUsed, "\n")); }