我被告知使用Thread.Sleep()
是一个糟糕的解决方案,有时人们会希望在同步方法的一系列动作中产生一些时间间隔。
另一方面,我有两个不同的线程,它们在我的程序的运行时间和一个共享对象中都是活动的,当我在该共享对象中使用Object.wait(long)时,它会导致我的GUI冻结一段时间
对于这个问题,什么是更好的解决方案?
更新 这部分代码包括一个以GUI开头的线程:
class temperatureUp extends Thread
{
@Override
public void run()
{
while(true)
{
try
{
GBC.increaseTemp();
updateSystemStatus();
}
catch(Exception ex)
{
StringWriter w = new StringWriter();
ex.printStackTrace(new PrintWriter(w));
txtLog.setText(w + "\n" + txtLog.getText());
}
}
}
};
这是共享对象中的同步方法,GBC:
class temperatureUp extends Thread
{
@Override
public void run()
{
while(true)
{
try
{
GBC.increaseTemp();
updateSystemStatus();
}
catch(Exception ex)
{
StringWriter w = new StringWriter();
ex.printStackTrace(new PrintWriter(w));
txtLog.setText(w + "\n" + txtLog.getText());
}
}
}
};
答案 0 :(得分:7)
不要在同步方法内睡觉!不要在GUI事件处理程序/方法中等待!
拆分同步操作,以便在GUI线程上下文中不调用Sleep()调用。
也许使用InvokeLater()作为第二位。
答案 1 :(得分:4)
您可以缩小synchronize
语句的范围。例如,如果您正在同步整个方法
public synchronized void foo()
您可以删除修改器并使用同步块
synchronized (this) {
// ...
}
并尽可能将Thread.sleep()
移到此块之外。仅同步那些修改共享数据状态的语句。
关于Swing的许多线程问题都与Event Dispatcher Thread有关,可以很容易地解决它。我建议你读一读。
一点背景,为什么你不应该在同步块中调用Thread.sleep()
:
在按住锁定时休眠或等待。使用a调用Thread.sleep 持有的锁可以防止其他线程长时间取得进展 时间,因此是一个潜在的严重的生活危险。调用 具有两个锁的Object.wait或Condition.await构成类似 冒险。 [JCIP]
答案 2 :(得分:0)
我会使用监视器:http://www.artima.com/insidejvm/ed2/threadsynch4.html 也许通过notify或notifyAll你可以解决它。祝你好运!
答案 3 :(得分:0)
始终保留负责处理GUI的事件调度程序线程(EDT),远离任何非UI工作。另外,不要同步整个方法,而是同步原子语句
synchronized(this){
//...
}
答案 4 :(得分:-1)
您可以尝试以下代码:
public static void delay(int waitTime) {
long endTime = System.currentTimeMillis() + (waitTime * 1000);
while (System.currentTimeMillis() < endTime) {}
}
呼叫延迟(5)。控制将等待5秒钟。