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

如何在Java中将秒表制作为线程?,java,multithreading,time,Java,Multithreading,Time,我正在尝试实现一个类似于的秒表,但它是一个线程。 我的secondsCenter类实现了Runnable,然后调用其“start方法将创建一个线程作为局部变量。 这个线程似乎与run方法中的第一行冲突:this.runningTime=System.currentTimeMillis()…因为while(this.runningTime


我正在尝试实现一个类似于的秒表,但它是一个
线程


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

这个线程似乎与
run
方法中的第一行冲突:
this.runningTime=System.currentTimeMillis()…因为while(this.runningTime
的条件
从未中断(无限循环)。。。


那么,让一个类既实现了
Runnable
又包含了它的“
线程”
,这是不正确的吗?



下面是包含main方法的类:

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

…和秒计数器类:

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
公共类SecondsCenter实现可运行{
私有int totalSeconds,currentSecond;
私有长启动时间、运行时间、结束时间;
私有线程;
公共秒中心(整数秒){
this.totalSeconds=totalSeconds;
}
public int getCurrentSecond(){
返回这个.currentSecond;
}
@凌驾
公开募捐{
this.runningTime=System.currentTimeMillis();
//这是一个无限循环,但不应该是:
while(this.runningTime
实际上,这应该是一个无限循环。看看你的环

while (this.runningTime < this.endTime) {
    this.currentSecond = (int)(this.endTime - this.runningTime) / 1000;
}
您甚至可以将其组合(或删除变量
runningTime
):

public void run(){
而((this.runningTime=System.currentTimeMillis())
实际上,这应该是一个无限循环。看看你的环

while (this.runningTime < this.endTime) {
    this.currentSecond = (int)(this.endTime - this.runningTime) / 1000;
}
您甚至可以将其组合(或删除变量
runningTime
):

public void run(){
而((this.runningTime=System.currentTimeMillis())
哦,哈,我完全错过了,多哈!现在它工作正常了,谢谢@Quincunx的帮助。有趣的是,我不知道你们可以设置一个值,然后使用它作为while循环的条件,谢谢@Quincunx!这似乎仅在设置位于括号中时有效,例如:
while((This.runningTime=System.currentTimeMillis())
…由于
@IanCampbell的运算符优先级问题,它在没有括号的情况下无法编译,这是因为赋值运算符也返回它指定的值。它只使用括号,因为赋值运算符的值最低,所以没有括号,我们得到
this.runningTime=(System.currentTimeMillis()
。括号的捕捉很好。哦,哈,我完全错过了,doh!现在它工作正常了,谢谢@Quincunx的帮助。有趣的是,我不知道你们都可以设置一个值作为while循环的条件,谢谢@Quincunx!这似乎只在设置在括号中时起作用,就像这样:
while((this.runningTime=System.currentTimeMillis())
…由于
@IanCampbell的运算符优先级问题,它在没有括号的情况下无法编译,这是因为赋值运算符也返回它指定的值。它只使用括号,因为赋值运算符的值最低,所以没有括号,我们得到
this.runningTime=(System.currentTimeMillis()第二计数器//Cux>类中消除<代码> StistTime/Cuff>变量,并且可能通过毫秒而不是秒到它的构造函数来简化一些单元康弗。我可以用<代码> java。UTIL。定时器< /C>代替,但是我只是用我的方式来测试线程。否则,我不会注意到任何问题的分离或违反了干。你能建议什么?这是很多代码。我会考虑如何简化它来做你想做的事。删除
secondsCenter
类中的
startTime
变量,并可能将毫秒(而不是秒)传递给它的“构造函数”,以简化一些单位转换内容。我可以使用
java.util.Timer
来代替,但我只是以自己的方式尝试线程。否则,我不会注意到任何错误关注的问题或违反DRY法规的行为。您有什么建议?