如何将秒表作为Java中的线程?

时间:2013-11-09 06:03:54

标签: java multithreading time


我正在尝试实施与Is there a stopwatch in Java?类似的秒表,但作为Thread

我的SecondsCounter类实现Runnable,然后调用其'start方法将创建一个线程作为局部变量。

看起来好像这个帖子与run方法中的第一行有冲突:this.runningTime = System.currentTimeMillis(); ...因为条件while (this.runningTime < this.endTime) 从未打破(一个无限循环)...

因此,如果一个实现Runnable 的类包含其“Thread,那么这是不正确的吗?



这是具有主要方法的类:

public class MultithreadingTest {

    public static void main(String[] args) {
        int totalSeconds = 5;
        SecondsPrinter printer = new SecondsPrinter(totalSeconds);
        printer.startPrinting();
    }
} // end of class


......秒打印机类:

public class SecondsPrinter {

    // composition here:
    private SecondsCounter clock;

    public SecondsPrinter(int totalSeconds) {
        this.clock = new SecondsCounter(totalSeconds);
    }

    public void startPrinting() {
        this.clock.start();
        while (this.clock.isRunning()) {

            // this is incorrectly always printing the maximum seconds value:
            System.out.println(this.clock.getCurrentSecond());
        }
    }
} // end of class


......和秒计数器类:

public class SecondsCounter implements Runnable {

    private int totalSeconds, currentSecond;
    private long startTime, runningTime, endTime;
    private Thread thread;

    public SecondsCounter(int totalSeconds) {
        this.totalSeconds = totalSeconds;
    }

    public int getCurrentSecond() {
        return this.currentSecond;
    }

    @Override
    public void run() {
        this.runningTime = System.currentTimeMillis();

        // this is an infinite loop, but it shouldn't be:
        while (this.runningTime < this.endTime) {
            this.currentSecond = (int)(this.endTime - this.runningTime) / 1000;
        }

        // this code is never reached:
        this.stop();
    }

    public void start() {
        this.startTime = System.currentTimeMillis();
        this.runningTime = this.startTime;
        this.endTime = this.startTime + (this.totalSeconds * 1000);

        // multithreading here:
        this.thread = new Thread(this);
        this.thread.start();
    }

    public boolean isRunning() {
        return this.thread.isAlive();
    }

    public void stop() {
        this.thread.interrupt();
        this.thread = null;
    }
} // end of class

1 个答案:

答案 0 :(得分:4)

实际上,这应该是一个无限循环。看看你的循环。

while (this.runningTime < this.endTime) {
    this.currentSecond = (int)(this.endTime - this.runningTime) / 1000;
}

条件说它会在runningTime < endTime时循环。 runningTime在哪里更新?如果你在循环中添加这样的东西,它应该可以工作:

public void run() {
    this.runningTime = System.currentTimeMillis();

    // no longer an infinite loop
    while (this.runningTime < this.endTime) {
        this.currentSecond = (int)(this.endTime - this.runningTime) / 1000;
        this.runningTime = System.currentTimeMillis();
    }

    // this code is now reached.
    this.stop();
}

您甚至可以将它组合(或完全删除变量runningTime):

public void run() {
    while ((this.runningTime = System.currentTimeMillis()) < this.endTime) {
        this.currentSecond = (int)(this.endTime - this.runningTime) / 1000;
    }

    this.stop();
}