Thread.Sleep在Java中的替代品

时间:2012-07-28 11:22:58

标签: java multithreading swing jframe thread-sleep

我被告知使用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());
            }
        }
        }
    };

5 个答案:

答案 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秒钟。