【发布时间】:2015-12-02 21:14:35
【问题描述】:
我试图在 jpanel 中显示时间,而后台线程执行昂贵的操作。显然时间线程应该比后台线程获得更高的优先级才能准确显示时间。
我已经编写了以下解决方案,但我确信它可以做得更好。你有什么建议?
另外:如何在不使用 .stop() 的情况下正确关闭后台线程?
编辑:在没有优先设置的情况下测试了程序后,它也可以工作,但我真的不知道为什么。
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.WindowConstants;
public class Test1 extends JPanel{
private static final long serialVersionUID = 1L;
private int time = 23*3600+59*60+30;
private Thread operationThread;
public Test1(){
JLabel text = new JLabel();
Timer timeDisplayer = new Timer(1000, e -> {
//Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
text.setText((time/3600)%24+":"+(time/60)%60+":"+(time%60));
time+=1;
});
timeDisplayer.setInitialDelay(0);
JButton b = new JButton("Restart operation");
b.addActionListener(arg0 -> makeNewThread());
add(b);
add(text);
timeDisplayer.start();
}
private void makeNewThread(){
if(operationThread!=null && operationThread.isAlive())
operationThread.stop();
operationThread = new Thread(() -> {
//Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
//expensiveOperation();
});
operationThread.start();
}
public static void main(String[] args){
JFrame f = new JFrame();
Test1 t = new Test1();
f.setLocation(400,50);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setSize(100,100);
f.setContentPane(t);
f.setVisible(true);
}
}
【问题讨论】:
-
显然时间线程应该获得更高的优先级...... 关于线程优先级的决定并不总是显而易见的。您需要多精确的时间显示?请记住,您所做的只是将其显示在屏幕上。
-
另外,请注意过早的优化。你问这个问题是不是因为你已经试过了,结果不满意?或者您是否试图预测可能存在或不存在的问题?
-
不要假设
Timer或Thread的准确性,这些都不能保证他们等待的时间是准确的,只是它会“至少”给定的时间。使用锚值并计算过去的时间量 -
该程序按我希望的方式工作,我只是好奇这是否是一个好方法。而且我不明白为什么后台线程不会影响 Timer 以及如何不停地关闭后台线程。 @MadProgrammer 所以我应该使用 System.currentTimeMillis() ?
-
疯狂物理学家几乎回答了所有问题。但是如何避免 stop() ?
标签: java multithreading swing