我有以下扩展Thread类的“秒表”的代码:
package StopWatch;
//Code taken from:
//https://stackoverflow.com/questions/9526041/how-to-program-for-a-stopwatch
public class Stopwatch extends Thread {
private long startTime;
private boolean started;
public void startTimer() {
this.startTime = System.currentTimeMillis();
this.started = true;
this.start();
}
public void run() {
while(started){/*currentTimeMillis increases on its own */}
System.out.println("timer stopped");
}
public int[] getTime() {
long milliTime = System.currentTimeMillis() - this.startTime;
int[] time = new int[]{0,0,0,0};
time[0] = (int)(milliTime / 3600000); //gives number of hours elapsed
time[1] = (int)(milliTime / 60000) % 60; //gives number of remaining minutes elapsed
time[2] = (int)(milliTime / 1000) % 60; //gives number of remaining seconds elapsed
time[3] = (int)(milliTime); //gives number of remaining milliseconds elapsed
return time;
}
public void stopTimer() {
this.started = false;
}
}我在下面的driver类中测试它:
import StopWatch.Stopwatch;
public class StopWatchTest {
public static void main(String[] args) {
Stopwatch stopwatch = new Stopwatch();
stopwatch.startTimer();
int sum = 0;
for (long i = 0; i < 100000; i++) {
sum++;
}
int[] time = stopwatch.getTime();
for (int i = 0; i < 4; i++) {
if (i < 3) {
System.out.print(time[i]+":");
} else {
System.out.print(time[i]);
}
}
stopwatch.stopTimer();
}
}我的目的是使用秒表类的实例来测量不同代码块(例如driver类中的for循环)的性能,方法是让主线程中的这些秒表对象在执行我想要计算的代码块之前在单独的线程中启动计时器,然后在主线程中完成上述块的执行后让它们(秒表对象)停止它们的计时器。我知道有更简单和更容易的方法来做这件事,但我想试着这样做,作为一种“概念证明”,并简单地通过多线程变得更好,但我遇到了一些问题:
1)当我运行驱动程序类StopWatchTest时,我每次都会得到看似随机和任意的输出(但主要是0:0:0:0)
2)在我得到像0:0:0:0这样的输出之后,主线程(或者可能是秒表线程,我甚至不确定了)似乎从未停止执行
3)当我尝试使用断点等进行调试时,我会得到完全意想不到的行为,这取决于我放置断点的位置(主线程有时会完成执行,但会有像0:0:13:2112这样的随机输出,而其他时候我只是卡在秒表线程中)
第3点并不像第1点和第2点那样让我担心,因为我对当一个或多个线程在断点处暂停调试时多线程的行为了解有限(我怀疑当我中断主线程时,秒表线程会继续运行)。第1点和第2点更让我困扰,因为我看不出它们为什么会发生。
发布于 2020-03-23 03:25:55
开始之前,您应该将启动的布尔值标记为volatile:
private volatile boolean started;这应该是可行的,但它会造成一个繁忙的循环,这对您的CPU使用率非常不利。接下来,您应该看看wait()/notify()方法。
https://stackoverflow.com/questions/60803768
复制相似问题