繁体   English   中英

在Java中通过多个线程生成唯一的素数

[英]Generate unique prime numbers by multiple threads in Java

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

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;
    }
}

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

谢谢你的帮助。

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

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

value = atomicInt.addAndGet(1000);

增加了1000 atomicInt和套value ,以价值atomicInt之前立即添加成功。 因此,您可以将value视为分配给当前线程进行搜索的 1000 个整数范围的开始。

另一个提示:如果您想要更好的性能,请查看埃拉托色尼筛

我猜你这样做是作为家庭作业或学习练习,所以我不会为你编码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM