为什么Thread.sleep()或TimeUnit.SECONDS.sleep()会延迟先前语句的执行而不是从调用sleep()的地方暂停

时间:2018-04-06 07:53:29

标签: java delay sleep

我正在做一件简单的事情,打印错误信息,延迟执行5秒然后调用另一个函数,这是代码

public void saveAndDisplay() throws InterruptedException{
//printing error message
if(saveValuesToDatabase()){
        System.out.println("done");
        errorType = "Done, you will be redirected to MainProject";
        String message = "<html><body><font color='red'>"
            + errorType
            + "</font></body></html>";
        lblError.setText(message);
    } else {
        System.out.println("not done");
        errorType = "Some problem occured, try again";
        String message = "<html><body><font color='red'>"
            + errorType
            + "</font></body></html>";
        lblError.setText(message);
    }

 //delaying by 5 seconds
 //Thread.sleep(5000); or
 TimeUnit.SECONDS.sleep(5);

 //now calling another function
 doSomethingElse();
}

而不是显示错误消息 - 然后延迟 - 然后调用doSomethingElse(),执行首先延迟5秒,然后显示错误消息,然后调用doSomethingElse()。 这是我的理解,因为我知道语句会在java中逐行执行,那么为什么Thread.sleep(5000)TimeUnit.SECONDS.sleep(5)会先被执行,即使它没有写在那里?

任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:6)

我认为您的lblErrorJLabel 在这种情况下,标签的值是直接设置的,但是直到睡眠之后控制才会返回到AWT线程。因此,标签不会在屏幕上更新。

尝试使用SwingUtilities.invokeAndWait()

您的代码可能如下所示:

// Compose message to put in label
// Must be 'final'
final String message = ...;

// Create runnable that sets the label
Runnable label_setter;
label_setter = new Runnable()
{
  @Override
  public void run()
  {
    lblError.setText(message);
  }
};

// Set label within AWT thread and wait for it to finish
SwingUtilities.invokeAndWait(label_setter);

// Now we can wait
Timeunit.SECONDS.sleep(5);

...

答案 1 :(得分:2)

也许我错了,但是用户here似乎有你的问题,这是因为他用睡眠方法睡了整个GUI,所以gui更新只在延迟后发生。 (我假设你正在使用java swing)

答案 2 :(得分:2)

Swing计时器在指定的延迟后触发一个或多个动作事件,建议在处理GUI时使用javax.swing.Timer而不是java.util.concurrent.TimeUnitjava.lang.Threadjava.util.Timer相关任务,因为Swing计时器都共享相同的,预先存在的计时器线程,并且GUI相关任务在事件派发线程上自动执行。 更多信息here

这是适合我的代码

public void saveAndDisplay() throws InterruptedException{
//printing error message
if(saveValuesToDatabase()){
    ...
}
Timer timer = new Timer(5000, new ActionListener() {    
    @Override
    public void actionPerformed(ActionEvent arg0) {
        doSomethingElse();
    }
    });
    timer.setRepeats(false);
    timer.start();
}

我认为问题是因为Thread.sleep()延迟了当前线程,即事件调度线程(EDT),它处理与GUI相关的任务,这就是lblError不存在的原因显示,直到计时器在5秒后释放线程。