[英]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.