跟踪多线程Java程序的总执行时间 [英] Track total execution time of multi-thread java program

查看:96
本文介绍了跟踪多线程Java程序的总执行时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Java程序,用于检查数字是否为质数.我试图通过使用单独的线程检查不同的数字来使其平行.

I have a java program that checks if numbers are prime. I tried to make it parallel by checking different numbers using separate threads.

这是我的顺序程序primeSeq.java:

Here is my sequential program, 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));

            }

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

这是我尝试对其进行并行化的primePar.java:

And here is my attempt at parallelizing it, 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++)
            {

                Thread newThread = new MyThread(args[i]);
                newThread.start();
            }

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

这是这些的输出:

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:

$ 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

由于所有线程同时启动,因此我的并行程序似乎运行正常.但是,总执行时间不是我想要的(它表示0毫秒).我该如何更改它以便跟踪所有线程完成所需的总执行时间(对于上面的输出,将为179毫秒)?

It seems that my parallel program is performing correctly since all the threads start at the same time. However, the total execution time is not what I wanted (it says 0 milliseconds). How can I change it so that it tracks the total execution time it takes for all the threads to finish (For the above output, it would be 179 milliseconds)?

推荐答案

如果您想要整个程序的执行时间,则您的主线程必须等待其他线程完成后才能计算.之所以是0 milliseconds,是因为在线程创建并启动后,当线程仍在后台运行时,主线程会立即进入最终打印.

If you want the execution time of the overall program, your main thread has to wait for the other threads to finish before calculating that. It is 0 milliseconds because after the threads are created and started the main thread instantly goes to the final print while your threads are still running in the background.

在这种情况下,您需要收集拥有的线程,然后在它们上调用join().此方法告诉线程从何处进行调用(在本例中为主线程),以等待调用该方法的线程在继续之前终止.这样,您将确保所有线程在主线程继续进行总执行时间的计算之前就完成了计算.

In this case you need to collect the threads you have and then call join() on them. This method tells the thread from where the call happens - in this case the main thread - to wait for the thread, that you called the method on, to terminate before continuing. By doing this you will be sure that all the threads finished calculation before the main thread continues to the calculation of the overall execution time.

类似的事情应该起作用:

Something like this should work:

long startTime = System.nanoTime();

List<Thread> threads = new ArrayList<>();

for(int i=0;i< args.length;i++)
{

    Thread newThread = new MyThread(args[i]);
    newThread.start();
    threads.add(newThread);
}

threads.forEach(t -> {
    try {
        t.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
});

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

此处以获取更多信息.

这篇关于跟踪多线程Java程序的总执行时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆