【问题标题】:Generate unique prime numbers by multiple threads in Java在Java中通过多个线程生成唯一的素数
【发布时间】:2020-06-27 05:57:58
【问题描述】:

在下面的这段代码中,多个生产者线程有时会生成相同的素数。如何确保不同的生产者始终生成唯一的素数?

public class UniquePrimes {


    private static BlockingQueue<Integer> linkedBlockingQueue = new LinkedBlockingQueue<Integer>(); 
    static ConcurrentHashMap<Integer, String> primesproduced = new ConcurrentHashMap<Integer, String>();

    public static void main(String[] args) {

        Scanner reader = new Scanner(System.in);
        System.out.print("Enter number of threads you want to create: ");
        int NOOFTHREADS = reader.nextInt();
        reader.close();

        ExecutorService executorPool = Executors.newFixedThreadPool(NOOFTHREADS);

        AtomicInteger currentPrime = new AtomicInteger();
        Runnable producer = () -> {
            String threadName = Thread.currentThread().getName();

            int p = 0;
            try {

                p = generateNextPrime(currentPrime.incrementAndGet());
                linkedBlockingQueue.put(p);
                primesproduced.put(p, threadName);
                System.out.println("Thread " + threadName + " produced prime number " + p);

            } catch (InterruptedException e) {

                e.printStackTrace();
            }
        };



        List<Runnable> tasks = new ArrayList<Runnable>();

        for (int i = 0; i < NOOFTHREADS; i++) {
            tasks.add(producer);

        }

        CompletableFuture<?>[] futures = tasks.stream().map(task -> CompletableFuture.runAsync(task, executorPool))
                .toArray(CompletableFuture[]::new);

        CompletableFuture.allOf(futures).join();
        executorPool.shutdown();

        System.out.println("\nTotal unique primes produced: " + primesproduced.size() + " and they are: ");


        System.out.print(
        primesproduced.entrySet().stream().filter(map -> map.getKey().intValue()>0).map(k -> "[" + k + "]").collect(Collectors.joining(",")));

        }
    }

    private static int generateNextPrime(int currentPrime) {    

        currentPrime++;
        if (currentPrime < 2) {
            currentPrime = 2;

            return currentPrime;

        }
        for (int i = 2; i < currentPrime; i++) {
            if (currentPrime % i == 0) {
                currentPrime++;
                i = 2;
            } else {
                continue;
            }
        }       
        return currentPrime;
    }
}

目前,多个生产者可以生成相同的质数。 我如何确保每个生产者都产生一个以前没有其他生产者产生的新质数?

感谢您的帮助。

【问题讨论】:

    标签: java multithreading java.util.concurrent


    【解决方案1】:

    您需要不同的策略。您当前的策略是让线程在currentPrime + 1 开始搜索素数。由于每个线程都在做同样的事情,这意味着它们将搜索重叠区域以查找素数。这是低效的(重复工作),并导致两个或线程偶尔发现相同的素数。

    更好的策略是确保每个线程搜索不同的范围。例如

    value = atomicInt.addAndGet(1000);
    

    将 1000 添加到 atomicInt 并将 value 设置为紧接在成功添加之前的 atomicInt 的值。因此,您可以将value 视为分配给当前线程进行搜索的 1000 个整数范围的开始。

    另一个提示:如果您想要更好的性能,请查看Sieve of Eratosthenes

    我猜你是把它当作家庭作业或学习练习,所以我不会为你编写代码。

    【讨论】:

    • 感谢您的建议和链接。我会努力的。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2021-08-30
    • 2021-05-09
    • 1970-01-01
    • 1970-01-01
    • 2012-05-09
    • 2011-12-28
    相关资源
    最近更新 更多