简体   繁体   English

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

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

In this code below multiple producer threads sometimes generate the same prime numbers.在下面的这段代码中,多个生产者线程有时会生成相同的素数。 How I can ensure that different producers always generate a unique prime number?如何确保不同的生产者始终生成唯一的质数?

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

Currently multiple producers can generate the same prime value.目前,多个生产者可以产生相同的素数。 How can I ensure that each producer generates a new prime value not generated previously by other producers?我如何确保每个生产者生成一个新的素值,以前其他生产者没有生成?

Thanks for any help.谢谢你的帮助。

You need a different strategy.你需要一个不同的策略。 Your current strategy is for threads to start searching for a prime at currentPrime + 1 .您当前的策略是让线程开始在currentPrime + 1处搜索素数。 Since each thread is doing the same thing, which means that they will be searching overlapping regions to primes.由于每个线程都在做同样的事情,这意味着它们将搜索重叠区域到素数。 This is inefficient (duplicated work), and leads to two or threads occasionally discovering the same prime.这是低效的(重复工作),并导致两个或线程偶尔发现相同的素数。

A better strategy is to make sure that each thread searches a different range.更好的策略是确保每个线程搜索不同的范围。 For example例如

value = atomicInt.addAndGet(1000);

adds 1000 to atomicInt and sets value to the value of atomicInt immediately prior to the successful add.增加了1000 atomicInt和套value ,以价值atomicInt之前立即添加成功。 So you could view value as the start of a range of 1000 integers that are assigned to the current thread for searching.因此,您可以将value视为分配给当前线程进行搜索的 1000 个整数范围的开始。

Another hint: look at the Sieve of Eratosthenes if you want better performance.另一个提示:如果您想要更好的性能,请查看埃拉托色尼筛

I am guessing that you are doing this as a homework or learning exercise, so I won't code it for you.我猜你这样做是作为家庭作业或学习练习,所以我不会为你编码。

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

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