解决方案 »

  1.   

    首先取区间3-X^1/2,然后把区间按线程数量分段
    然后各个线程运行指定区间的X%n,如果全部线程都不能整除,则是素数,返回主线程由主线程查看判断结果
      

  2.   

    写了一个多小时,调试了一晚上,应该没有问题了,支持大于等于2的所有long型数的判断,线程数选择要合理,小于int最大值的数一个线程就够了,多了没有帮助,超大的数也不要多于你的CPU核心数,不然反倒会更慢。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  = new SharedMark(threads);

    if (threads == 1) {
    checkers[0] = new IntervalChecker(n, 7, sqrt, );
    } else {
    checkers[0] = new IntervalChecker(n, 7, interval + 1, );
    for (int i = 1; i < threads - 1; i++) {
    checkers[i] = new IntervalChecker(n, interval * i + 7, 
    interval * (i + 1) + 1, );
    }
    checkers[threads - 1] = new IntervalChecker(n, interval + 7, sqrt, );
    }

    for (int i = 0; i < threads; i++) {
    new Thread(checkers[i]).start();
    }

    synchronized (.lock) {
    do {
    try {
    .lock.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }

    } while (.runningThreads > 0);
    }

    return .unknown;
    }

    static class IntervalChecker implements Runnable {
    long n, from, to;
    final SharedMark ;

    IntervalChecker(long n, long from, long to, SharedMark ) {
    this.n = n;
    this.from = from;
    this.to = to;
    this. = ;
    }

    @Override
    public void run() {
    final long[] steps = {4, 2, 4, 2, 4, 6, 2, 6};
    int j = 0;

    for (long i = from; .unknown && i <= to; i += steps[j &= 7], j++) {
    if (n % i == 0) {
    //System.out.println("Divisible by " + i);

    .unknown = false;
    break;
    }
    }

    synchronized (.lock) {
    .runningThreads--;
    .lock.notify();
    }
    }

    }

    static class SharedMark {
    boolean unknown;
    final Object lock;
    int runningThreads;
    SharedMark(int threads) {
    unknown = true;
    lock = new Object();
    runningThreads = threads;
    }
    }
    }
      

  3.   

    嗷。。 推荐个帖子http://blog.csdn.net/program_think/article/details/7032600/其实这种问题好多都归于数学问题, 用多线程是要看场景的
      

  4.   

    计算机是一门实践科学,所以,我们一般都是比较务实的人。
    楼主的这个问题,就经验而谈,没有实际意义。
    多线程技术的应用场景,主要就两个方面:一、CPU密集型运算;二、异步阻塞处理。
    楼主求一个数是否是素数,说实话,真没必要多线程。耗时时间长,占用内存多,编程复杂度相对要大。既然楼主是为了学习而学习,那么,我也只能用笨办法来解决了。
    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));
    }}