我对Java相当陌生,为了使用wait()
或sleep()
在我的代码的一部分上开始使用其他线程,并让其他代码继续运行,我开始使用不同的线程。
对于此项目,我将JFrame
与javax.swing.*
和java.awt.*
导入一起使用。我想做的是让其中一个线程(在我的代码中是主线程,启动线程)允许玩家在井字游戏板上选择一个空间,当他们单击它时,它将更改图标,并且然后AI将等待1秒钟,然后再从我创建的第二个线程进行回放。
不幸的是,每当我调用ait.sleep(1000)
(ait
是我的线程名称)时,两个线程都将等待1秒钟,然后再执行它们。谁能告诉我为什么休眠一个线程会停止我的整个执行?
最佳答案
谁能告诉我为什么睡一个线程阻止我的全部
执行
为了更好地说明您的Swing GUI是在其自己的特殊线程上创建的,该线程与main()
和其他代码将在其上运行的线程分开,这是通过在SwingUtilities.invokeXXX
块中创建Swing组件来完成的(即使您尚未执行此操作,您的GUI也将运行)在一个名为initial thread的线程上)。现在,如果您只是在sleep
上调用Event Dispatch Thread
(或与此相同的Thread
),它将等待对Thread.sleep
的调用完成。现在,由于所有Swing事件都在EDT上处理,我们通过调用sleep(..)
暂停执行,因此暂停了UI事件的处理,因此GUI被冻结(直到sleep(..)
返回)。
您不应该在 Thread.sleep(..)
上使用Event Dispatch Thread
(或任何睡眠会导致不必要的执行阻塞的Thread
),因为这会导致UI冻结。
Here是一个很好的示例,它准确地演示了在GUI的EDT上调用Thread.sleep(..)
引起的这种有害行为。
而是使用:
int delay=1000;// wait for second
Timer timer = new Timer(delay, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
//action that you want performed
}
});
//timer.setRepeats(false);//the timer should only go off once
timer.start();
或如果没有创建/修改Swing组件:
Thread.sleep(int milis)
(但这是IMO中的最后一个选择)更新
Swing Timer
/ SwingWorker
仅在Java 1.6中添加,但是TimerTask
和Thread
代表了更长的正弦Java 1.3和JDK 1,因此您甚至可以使用上述两种方法中的任何一种,并在/ wrap中创建/操作Swing组件的包装调用SwingUtilities/EventQueue#invokeXX
块;多数民众赞成在过去的事情方式:P