【发布时间】:2016-09-01 03:43:56
【问题描述】:
最近我做了一个非常基本的程序。具有暂停功能的计时器。它使用 3 个线程,2 个用于 Swing,1 个用于主线程。
对于这个程序,主线程中应该有一个增量时间计数部分。我做了一个非常基本的系统;
while(true)
{
long now = System.currentTimeMillis();
if(!sessionPaused)
{
if(now-programLastMs>1000)
{
save();
programLastMs = now;
}
sessionMs += now-sessionPrevMs;
overallMs += now-sessionPrevMs;
sessionPrevMs = now;
sessionLabel.setText(formatMillis("This Session:<br/>",sessionMs));
overallLabel.setText(formatMillis("Overall:<br/>", overallMs));
}
}
以上代码导致 CPU 使用率过高。然后我将该代码块替换为:
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
long now = System.currentTimeMillis();
if(!sessionPaused)
{
if(now-programLastMs>1000)
{
save();
programLastMs = now;
}
sessionMs += now-sessionPrevMs;
overallMs += now-sessionPrevMs;
sessionPrevMs = now;
sessionLabel.setText(formatMillis("This Session:<br/>",sessionMs));
overallLabel.setText(formatMillis("Overall:<br/>", overallMs));
}
}
}, 0, 1);
问题就解决了。我只是想知道其中的原因。还有什么是创建程序循环的最佳方式?
【问题讨论】:
-
您的
while(true)循环没有任何暂停,因此循环不断运行并不断消耗CPU。调度使您的run方法仅在调度时执行。 -
所以如果我让调度程序每 50 纳秒调用一次,会不会一样?还有什么是创建程序循环的最佳方式? @Berger
-
这取决于你的
run方法的持续时间,但是50纳秒真的很低,你需要这么高的频率吗?然而,正如您所见,最好让您的应用程序呼吸,所以要么使用调度程序,要么将Thread.sleep添加到您的while循环中。 -
你也不应该阻塞 Swing 线程。如果您在事件处理方法中执行长/无限循环,您的程序将无法重绘。请阅读concurrency in swing
-
所以基本上 Thread.sleep(1) 在 while(true) 循环中与 Timer 有相同的效果吗? @Berger
标签: java multithreading loops timer