import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; class PrimeTester { public static void main(String[] args) throws InterruptedException { final AtomicInteger primeCount = new AtomicInteger(); // ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); // ExecutorService executor = Executors.newCachedThreadPool(); ExecutorService executor = new ThreadPoolExecutor(0, 1, 60, TimeUnit.SECONDS, new LinkedBlockingDeque()); for (int i = 0; i < 100; i++) { final int start; final int end; if (i == 0) { // only start at 2 start = 2; } else { start = i * 100; } if (i == 99) { // end at 100.000 instead of 99.999 end = 100_001; } else { end = (i + 1) * 100; } Runnable t = () -> { System.out.println("Testing " + start + " to " + (end - 1)); for (int j = start; j < end; j++) { if (isPrime(j)) { primeCount.incrementAndGet(); } if (j == (end - start) / 2 + start) { System.out.println("Waiting at " + j); try { Thread.sleep(50); System.out.println("Done waiting at " + j); } catch (InterruptedException e) { System.out.println("Thread interrupted: " + e.getMessage()); return; } } } }; executor.execute(t); } executor.shutdown(); executor.awaitTermination(10, TimeUnit.SECONDS); System.out.println("Total prime numbers: " + primeCount.get()); } private static boolean isPrime(int n) { if (n < 2) return false; if (n == 2) return true; for (int d = 2; d < n; d++) { if (n % d == 0) { return false; } } return true; } }