java - 跟踪多线程java程序的总执行时间
问题描述
我有一个检查数字是否为素数的 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));
}
long endTime = System.nanoTime();
System.out.println("Total time: " + TimeUnit.NANOSECONDS.toMillis(endTime - startTime) + " milliseconds");
}
}
}
这是我并行化它的尝试,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");
}
}
}
以下是这些的输出:
素序列:
$ 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 毫秒)?
解决方案
如果您想要整个程序的执行时间,您的主线程必须等待其他线程完成才能计算。这是0 milliseconds
因为在创建并启动线程后,主线程会立即进入最终打印,而您的线程仍在后台运行。
在这种情况下,您需要收集您拥有的线程,然后调用join()
它们。此方法告诉发生调用的线程(在本例中为主线程)等待您调用该方法的线程在继续之前终止。通过这样做,您将确保所有线程在主线程继续计算总执行时间之前完成计算。
像这样的东西应该工作:
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");
在这里查看更多信息。
推荐阅读
- mysql - Laravel - SQLSTATE [HY000]:一般错误:2031
- .htaccess - 我的网站被克隆到 3 个不同的域上,我该怎么办?
- spring-boot - 环境变量始终为空。科特林春天
- delphi - 从通过 Indy 检索的页面源获取 HTML 表单中的默认表单值的最简单方法是什么?
- css - 属性选择器的 Sass @each 循环
- android - CircleCI 中的单元测试因 org.gradle.internal.exceptions.LocationAwareException 而失败
- dart - 在 TextInputType 更改后控制器重置的 Flutter TextField
- python - 如何在python中沿曲线注释文本并旋转线条?
- kentico - Kentico - 网络分析仪表板不断刷新
- rabbitmq - RabbitMQ 服务器正在下降