[英]Finding prime number using BlockingQueue in Java with multi threading
I've implemented a multi thread program using BlockingQueue to test for a number is prime or not. 我使用BlockingQueue实现了一个多线程程序,以测试数字是否为质数。
The requirement is the program will prompt user to input a number and then the program will print every prime number from 2 to inputted number from user in ascending order. 要求是程序将提示用户输入数字,然后程序将按升序打印每个从2到用户输入数字的素数。
I have 3 class: NumberEnumerationTask for initialize BlockingQueue contains all numbers to be check, PrimeRunner for check the number is prime or not, PrimeChecker for the main class. 我有3类:NumberEnumerationTask用于初始化的BlockingQueue包含了所有的数字是检查,PrimeRunner为检查号是质不是,PrimeChecker主类。
NumberEnumerationTask.java NumberEnumerationTask.java
package multithread;
import java.util.concurrent.BlockingQueue;
public class NumberEnumerationTask implements Runnable {
private BlockingQueue<Integer> queue;
private Integer maximum;
public static Integer DUMMY = new Integer(0);
public NumberEnumerationTask(BlockingQueue<Integer> queue, Integer maximum) {
this.queue = queue;
this.maximum = maximum;
}
@Override
public void run() {
try {
enumerate();
queue.put(DUMMY);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* Create a BlockingQueue contain Integer number from 1 to maximum.
* @throws InterruptedException
*/
private void enumerate() throws InterruptedException {
for (int i = 2; i < maximum; i++) {
queue.put(i);
}
}
}
PrimeRunner.java PrimeRunner.java
package multithread;
import java.util.concurrent.BlockingQueue;
public class PrimeRunner implements Runnable {
private BlockingQueue<Integer> queue;
public PrimeRunner(BlockingQueue<Integer> queue) {
this.queue = queue;
}
@Override
public void run() {
try {
boolean done = false;
while (!done) {
Integer checkNumber = queue.take();
if (checkNumber == NumberEnumerationTask.DUMMY) {
queue.put(checkNumber);
done = true;
} else {
checkPrimeNumber(checkNumber);
}
}
} catch(InterruptedException e) {
e.printStackTrace();
}
}
private void checkPrimeNumber(Integer number) {
boolean isPrime = true;
for (int i = 2; i <= number / 2; i++) {
if (number % i == 0) {
isPrime = false;
queue.remove(number);
break;
}
}
if (isPrime == true) {
System.out.print(number + " ");
queue.remove(number);
}
}
}
PrimeChecker.java PrimeChecker.java
public class PrimeChecker {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter maximum number to check: ");
Integer number = sc.nextInt();
BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(number);
NumberEnumerationTask initialize = new NumberEnumerationTask(queue, number);
new Thread(initialize).start();
for (int i = 0; i <= number; i++) {
new Thread(new PrimeRunner(queue)).start();
}
sc.close();
}
}
The DUMMY variable is to signal completion. DUMMY变量用于表示完成。
When I run the program, sometime it's not print in ascending order, sometime it does. 当我运行该程序时,有时它不是按升序打印的,有时是的。
Enter maximum number to check: 100
输入要检查的最大数字:100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
Enter maximum number to check: 100
输入要检查的最大数字:100
2 3 5 7 11 13 17 19 23 29 31 41 43 47 37 59 61 53 67 71 73 79 83 89 97
2 3 5 7 11 13 17 19 23 29 31 41 43 47 37 59 61 53 67 71 73 79 83 89 97
Can someone tell me what is wrong with my code? 有人可以告诉我我的代码有什么问题吗? Thanks
谢谢
In PrimeChecker
, the following code is the cause: 在
PrimeChecker
,以下代码是原因:
for (int i = 0; i <= number; i++) {
new Thread(new PrimeRunner(queue)).start();
}
You create multiple PrimeRunner
instances and a thread for each of them, so something like below can happen: 您创建了多个
PrimeRunner
实例以及每个实例的一个线程,因此可能会发生以下情况:
If you run a single PrimeRunner
you can avoid such cases and it works as you expected. 如果只运行一个
PrimeRunner
,则可以避免这种情况,并且可以按预期运行。 If you still want to run multiple PrimeRunner
surrounding the following part by synchronized
block with an object in a static field of PrimeRunner
should solve the problem: 如果您仍然想通过与
PrimeRunner
静态字段中的对象进行synchronized
块PrimeRunner
围绕以下部分运行多个PrimeRunner
, PrimeRunner
应该可以解决该问题:
Integer checkNumber = queue.take();
if (checkNumber == NumberEnumerationTask.DUMMY) {
queue.put(checkNumber);
done = true;
} else {
checkPrimeNumber(checkNumber);
}
Thread safety is the major issue. 线程安全是主要问题。 In your code, queue is shared among threads which is being processed without any synchronization mechanism hence data corruption likely to happen hence unpredictable result.
在您的代码中,队列在正在处理的线程之间共享,没有任何同步机制,因此可能会发生数据损坏,从而导致不可预测的结果。 If you run it multiple times you might get different results.
如果多次运行它,可能会得到不同的结果。
Multi-threading could be used for prime check to speed up the main goal ie prime finding which could be achieved by splitting the big number N into multiple parts and individual thread would work upon these parts and one thread to aggregate the results. 多线程可用于素数检查以加快主要目标,即可以通过将大数N拆分为多个部分来实现素数查找,并且单个线程将在这些部分上工作,而一个线程将结果汇总。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.