首页 > 解决方案 > Java多线程没有停止

问题描述

对于一种扩展 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;
    }
}

我正在以下驱动程序类中对其进行测试:

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();
    }
}

我的意图是使用类 Stopwatch 的实例来测量各种代码块(例如驱动程序类中的 for 循环)的性能,方法是让主线程中的这些 Stopwatch 对象在执行块之前在单独的线程中启动一个计时器我要评估的代码,然后让它们(秒表对象)在主线程中的所述块执行完成后停止它们的计时器。我知道有更简单和更容易的方法来做到这一点,但我想尝试以这种方式作为一种“概念证明”,并通过多线程变得更好,但我遇到了一些问题:

1)当我运行驱动程序类 StopWatchTest 时,我每次都会得到看似随机和任意的输出(但主要是 0:0:0:0)

2)在我得到像 0:0:0:0 这样的输出之后,主线程(或者可能是秒表线程,我什至不确定)似乎永远不会停止执行

3)当我尝试使用断点等进行调试时,我得到完全出乎意料的行为,具体取决于我放置断点的位置(主线程有时会完成执行,但随机输出像 0:0:13:2112 和其他时候我只是卡住了在秒表线程中)

第 3 点并不像第 1 点和第 2 点那样关心我,因为我对当一个或多个线程在断点处暂停以进行调试时多线程的行为了解有限(我怀疑当我在主线程中中断时秒表线程继续运行)。第 1 点和第 2 点让我更加困扰,因为我不明白它们为什么会发生。

标签: javamultithreading

解决方案


为了让你开始,你应该将 boolean 标记为 volatile:

private volatile boolean started;

这应该可行,但它会造成一个繁忙的循环,这对您的 CPU 使用率非常不利。你应该看看wait()/notify()接下来的方法。


推荐阅读