62,614
社区成员
发帖
与我相关
我的任务
分享
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class PrimeUtil {
public static final int QUEUE_SIZE = 100;
private static final Operand POISON = new Operand();
private BlockingQueue<Operand> operands = new LinkedBlockingQueue<PrimeUtil.Operand>(QUEUE_SIZE);
private BlockingQueue<Operand> results = new LinkedBlockingQueue<PrimeUtil.Operand>(QUEUE_SIZE);
private boolean running = false;
private long number;
public PrimeUtil(long number) {
this.number = number;
}
static class Operand{
long dividend; //被除数
long divisor; //除数
long remainder; //余数
}
class Producer extends Thread{
public void run(){
try {
for(int i=2;running && i<number;i++){
Operand o = new Operand();
o.dividend = number;
o.divisor = i;
operands.put(o);
}
operands.put(POISON);
} catch (InterruptedException e) {
}
}
}
class Consumer extends Thread{
public void run(){
try {
while(running){
Operand o = operands.take();
if(o==POISON){
operands.put(o);
results.put(o);
break;
}
o.remainder = o.dividend % o.divisor;
results.put(o);
}
} catch (InterruptedException e) {
}
}
}
private boolean isPrime(){
Producer producer = new Producer();
Consumer consumer = new Consumer();
running = true;
producer.start();
consumer.start();
try {
while(running){
Operand o = results.take();
if(o==POISON){
running = false;
return true;
}
if(o.remainder==0){
running = false;
}
}
} catch (InterruptedException e) {
}
return false;
}
public static boolean isPrime(long number){
if(number==1 || number==2)return true;
return new PrimeUtil(number).isPrime();
}
/**
* 测试用例
*/
public static void main(String[] args) {
System.out.println(isPrime(5));
}
}
public class MultiThreadedIsPrime {
public static void main(String[] args) {
testWithASingleNumber();
findPrimeNumbers();
}
public static void findPrimeNumbers() {
int count = 0, threads = 2;
long from = 5000, to = 10000;
for (long i = from; i <= to; i++) {
if (isPrime(i, threads)) {
count++;
}
}
System.out.println("There are " + count +
" prime numbers on the interval [" + from +
"," + to + "]");
}
public static void testWithASingleNumber() {
long num = 9223372036854775783L;
int threads = 2;
System.out.println("Checking if " + num + " is a prime number.");
long time = System.currentTimeMillis();
if (isPrime(num, threads)) {
System.out.println(num + " is a prime number.");
} else {
System.out.println(num + " is not a prime number.");
}
time = System.currentTimeMillis() - time;
System.out.println("Time consumed: " + time);
}
public static boolean isPrime(long n, int threads) {
if (threads <= 0) {
throw new IllegalArgumentException("Illegal number of threads.");
}
if (n <= 1) {
throw new IllegalArgumentException("Illegal number.");
}
if (n <= 3 || n == 5 || n == 7) return true;
if ((n & 1) == 0 || n % 3 == 0 || n % 5 == 0) return false;
long sqrt = (long)Math.sqrt(n) + 1;
long interval = (((sqrt - 7) / 30 + 1) / threads) * 30;
if (interval == 0) {
throw new IllegalArgumentException("Too many threads.");
}
IntervalChecker[] checkers = new IntervalChecker[threads];
SharedMark mark = new SharedMark(threads);
if (threads == 1) {
checkers[0] = new IntervalChecker(n, 7, sqrt, mark);
} else {
checkers[0] = new IntervalChecker(n, 7, interval + 1, mark);
for (int i = 1; i < threads - 1; i++) {
checkers[i] = new IntervalChecker(n, interval * i + 7,
interval * (i + 1) + 1, mark);
}
checkers[threads - 1] = new IntervalChecker(n, interval + 7, sqrt, mark);
}
for (int i = 0; i < threads; i++) {
new Thread(checkers[i]).start();
}
synchronized (mark.lock) {
do {
try {
mark.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (mark.runningThreads > 0);
}
return mark.unknown;
}
static class IntervalChecker implements Runnable {
long n, from, to;
final SharedMark mark;
IntervalChecker(long n, long from, long to, SharedMark mark) {
this.n = n;
this.from = from;
this.to = to;
this.mark = mark;
}
@Override
public void run() {
final long[] steps = {4, 2, 4, 2, 4, 6, 2, 6};
int j = 0;
for (long i = from; mark.unknown && i <= to; i += steps[j &= 7], j++) {
if (n % i == 0) {
//System.out.println("Divisible by " + i);
mark.unknown = false;
break;
}
}
synchronized (mark.lock) {
mark.runningThreads--;
mark.lock.notify();
}
}
}
static class SharedMark {
boolean unknown;
final Object lock;
int runningThreads;
SharedMark(int threads) {
unknown = true;
lock = new Object();
runningThreads = threads;
}
}
}