为什么 Thread.sleep() 或 TimeUnit.SECONDS.sleep() 会延迟执行先前的语句,而不是从调用 sleep() 的地方暂停
Why does Thread.sleep() or TimeUnit.SECONDS.sleep() delays execution of previous statements instead pausing from where sleep() is called
我在做一件简单的事情,打印一条错误消息,延迟执行 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)
即使没有写在那里也会先执行?
如有任何帮助,我们将不胜感激。
我想你的 lblError
是 JLabel
.
在那种情况下,标签的值被直接设置,但控制权直到睡眠结束后才返回给 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);
...
也许我错了,但用户 here 似乎遇到了你的问题,这是由于他使用睡眠方法使整个 GUI 处于休眠状态,因此 gui 更新仅在延迟之后发生.
(我假设你正在使用 java 秋千)
一个Swing计时器在指定的延迟后触发一个或多个动作事件,建议在处理时使用javax.swing.Timer
而不是java.util.concurrent.TimeUnit
或java.lang.Thread
和java.util.Timer
使用 GUI-related 任务,因为 Swing 计时器都共享相同的 pre-existing 计时器线程,并且 GUI-related 任务自动在 event-dispatch 线程上执行。
更多信息 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()
延迟了当前线程 event-dispatch thread(EDT),它也处理 GUI-related 任务,这就是为什么 lblError
直到计时器在 5 秒后释放线程才显示。
我在做一件简单的事情,打印一条错误消息,延迟执行 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)
即使没有写在那里也会先执行?
如有任何帮助,我们将不胜感激。
我想你的 lblError
是 JLabel
.
在那种情况下,标签的值被直接设置,但控制权直到睡眠结束后才返回给 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);
...
也许我错了,但用户 here 似乎遇到了你的问题,这是由于他使用睡眠方法使整个 GUI 处于休眠状态,因此 gui 更新仅在延迟之后发生. (我假设你正在使用 java 秋千)
一个Swing计时器在指定的延迟后触发一个或多个动作事件,建议在处理时使用javax.swing.Timer
而不是java.util.concurrent.TimeUnit
或java.lang.Thread
和java.util.Timer
使用 GUI-related 任务,因为 Swing 计时器都共享相同的 pre-existing 计时器线程,并且 GUI-related 任务自动在 event-dispatch 线程上执行。
更多信息 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()
延迟了当前线程 event-dispatch thread(EDT),它也处理 GUI-related 任务,这就是为什么 lblError
直到计时器在 5 秒后释放线程才显示。