简体   繁体   English

在 Java 中使用线程的并行素数检查器

[英]Parallel prime number checker using threads in Java

I have a java program that checks if numbers are prime.我有一个 Java 程序来检查数字是否为素数。 I tried to make it parallel by checking different numbers using separate threads.我试图通过使用单独的线程检查不同的数字来使其并行。

I ran the programs and compared their execution times, but I am not seeing an improvement...我运行了程序并比较了它们的执行时间,但我没有看到改进......

Here is my sequential program, primeSeq.java:这是我的顺序程序,primeSeq.java:

import java.io.*;
import java.text.ParseException;
import java.util.concurrent.TimeUnit;
import java.lang.Object;

class primeSeq {

    static boolean isPrime(long n) {
        // Check base cases:
        // n < 2, n is 2 or 3, n is divisible by 2 or 3
        if(n < 2) return false;
        if(n == 2 || n == 3) return true;
        if(n%2 == 0 || n%3 == 0) return false;

        // Check if divisible by all numbers 6k +-1 up to sqrt(n)
        long sqrtN = (long)Math.sqrt(n)+1;
        for(long i = 6L; i <= sqrtN; i += 6) {
            if(n%(i-1) == 0 || n%(i+1) == 0) return false;
        }
        return true;
    }

    public static void main(String args[]) throws ParseException
    {
        if (args.length == 0){
            System.out.println("No args provided.");
        }
        else
        {
            long startTime = System.nanoTime();

            for(int i=0;i< args.length;i++)
            {
                long single_startTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
                boolean isPrime = isPrime(Long.parseLong(args[i]));
                long single_endTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
                System.out.println(args[i] + ": " + isPrime + "\tStart time: " + single_startTime + "\tEnd time: " + single_endTime + "\tElapsed time: " + (single_endTime - single_startTime));

                // boolean isPrime = isPrime(Long.parseLong(args[i]));
                // System.out.println(args[i] + ": " + isPrime);
            }

            long endTime = System.nanoTime();
            System.out.println("Total time: " + TimeUnit.NANOSECONDS.toMillis(endTime - startTime) + " milliseconds");
        }
    }
}

And here is my attempt at parallelizing it, primePar.java:这是我尝试并行化它,primePar.java:

import java.io.*;
import java.text.ParseException;
import java.util.concurrent.TimeUnit;
import java.lang.Object;

class MyThread extends Thread
{
    boolean isPrime(long n) {
        // Check base cases:
        // n < 2, n is 2 or 3, n is divisible by 2 or 3
        if(n < 2) return false;
        if(n == 2 || n == 3) return true;
        if(n%2 == 0 || n%3 == 0) return false;

        // Check if divisible by all numbers 6k +-1 up to sqrt(n)
        long sqrtN = (long)Math.sqrt(n)+1;
        for(long i = 6L; i <= sqrtN; i += 6) {
            if(n%(i-1) == 0 || n%(i+1) == 0) return false;
        }
        return true;
    }

    String threadName;
    public MyThread(String threadName)
    {
        super(threadName);
        this.threadName = threadName;
    }

    @Override
    public void run()
    {
        long startTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
        boolean isPrime = isPrime(Long.parseLong(threadName));
        long endTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
        System.out.println(threadName + ": " + isPrime + "\tStart time: " + startTime + "\tEnd time: " + endTime + "\tElapsed time: " + (endTime - startTime));
    }
}

class primePar {
    public static void main(String args[]) throws ParseException
    {
        if (args.length == 0){
            System.out.println("No args provided.");
        }
        else
        {
            long startTime = System.nanoTime();

            for(int i=0;i< args.length;i++)
            {
                try
                {
                    Thread newThread = new MyThread(args[i]);
                    newThread.start();
                    newThread.join();
                }
                catch (InterruptedException exc)
                {
                    System.out.println(exc); 
                }
            }

            long endTime = System.nanoTime();
            System.out.println("Total time: " + TimeUnit.NANOSECONDS.toMillis(endTime - startTime) + " milliseconds");
        }
    }
}

Here is the output of these:这是这些的输出:

PrimeSeq: PrimeSeq:

$ java primeSeq 1000000000000037 1000000000000091 1000000000000159 1000000000000187
1000000000000037: true  Start time: 143773080   End time: 143773182 Elapsed time: 102
1000000000000091: true  Start time: 143773183   End time: 143773284 Elapsed time: 101
1000000000000159: true  Start time: 143773284   End time: 143773400 Elapsed time: 116
1000000000000187: true  Start time: 143773400   End time: 143773510 Elapsed time: 110
Total time: 430 milliseconds

PrimePar: PrimePar:

$ java primePar 1000000000000037 1000000000000091 1000000000000159 1000000000000187
1000000000000037: true  Start time: 143746202   End time: 143746309 Elapsed time: 107
1000000000000091: true  Start time: 143746310   End time: 143746415 Elapsed time: 105
1000000000000159: true  Start time: 143746415   End time: 143746519 Elapsed time: 104
1000000000000187: true  Start time: 143746520   End time: 143746619 Elapsed time: 99
Total time: 418 milliseconds

It doesn't seem that my parallel program is actually running in parallel.看来我的并行程序实际上并没有并行运行。 How can I fix this?我怎样才能解决这个问题?

As pointed out by user "Dawood says reinstate Monica" in the comments, newThread.join() was the problematic command.正如用户“达伍德说恢复莫妮卡”在评论中指出的那样, newThread.join()是有问题的命令。

Removing this helps, as all the threads start at the same time:删除它会有所帮助,因为所有线程同时启动:

Updated primePar.java program:更新了 primePar.java 程序:

import java.io.*;
import java.text.ParseException;
import java.util.concurrent.TimeUnit;
import java.lang.Object;

class MyThread extends Thread
{
    boolean isPrime(long n) {
        // Check base cases:
        // n < 2, n is 2 or 3, n is divisible by 2 or 3
        if(n < 2) return false;
        if(n == 2 || n == 3) return true;
        if(n%2 == 0 || n%3 == 0) return false;

        // Check if divisible by all numbers 6k +-1 up to sqrt(n)
        long sqrtN = (long)Math.sqrt(n)+1;
        for(long i = 6L; i <= sqrtN; i += 6) {
            if(n%(i-1) == 0 || n%(i+1) == 0) return false;
        }
        return true;
    }

    String threadName;
    public MyThread(String threadName)
    {
        super(threadName);
        this.threadName = threadName;
    }

    @Override
    public void run()
    {
        long startTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
        boolean isPrime = isPrime(Long.parseLong(threadName));
        long endTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
        System.out.println(threadName + ": " + isPrime + "\tStart time: " + startTime + "\tEnd time: " + endTime + "\tElapsed time: " + (endTime - startTime));
    }
}

class primePar {
    public static void main(String args[]) throws ParseException
    {
        if (args.length == 0){
            System.out.println("No args provided.");
        }
        else
        {
            long startTime = System.nanoTime();

            for(int i=0;i< args.length;i++)
            {
                // try
                // {
                    Thread newThread = new MyThread(args[i]);
                    newThread.start();
                    // newThread.join();
                // }
                // catch (InterruptedException exc)
                // {
                //  System.out.println(exc); 
                // }
            }

            long endTime = System.nanoTime();
            System.out.println("Total time: " + TimeUnit.NANOSECONDS.toMillis(endTime - startTime) + " milliseconds");
        }
    }
}

New output:新输出:

$ java primePar 1000000000000037 1000000000000091 1000000000000159 1000000000000187
Total time: 0 milliseconds
1000000000000091: true  Start time: 144449191   End time: 144449354 Elapsed time: 163
1000000000000159: true  Start time: 144449191   End time: 144449355 Elapsed time: 164
1000000000000187: true  Start time: 144449191   End time: 144449357 Elapsed time: 166
1000000000000037: true  Start time: 144449191   End time: 144449370 Elapsed time: 179

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

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