Java 对单个线程使用sleep()
我对java相当陌生,我开始使用不同的线程,以便在代码的一部分上使用Java 对单个线程使用sleep(),java,multithreading,swing,event-dispatch-thread,thread-sleep,Java,Multithreading,Swing,Event Dispatch Thread,Thread Sleep,我对java相当陌生,我开始使用不同的线程,以便在代码的一部分上使用wait()或sleep(),而让其他部分仍然运行 对于这个项目,我将JFrame与javax.swing.*和java.awt.*导入一起使用。我试图做的是让其中一个线程(在我的代码中,它是主线程,起始线程)允许玩家在tic-tac趾板上选择一个空格,当他们单击它时,它将更改图标,然后AI将等待1秒,然后从我创建的第二个线程播放 不幸的是,每当我调用ait.sleep(1000)(ait是我的线程名)时,两个线程都会等待1秒才
wait()
或sleep()
,而让其他部分仍然运行
对于这个项目,我将JFrame
与javax.swing.*
和java.awt.*
导入一起使用。我试图做的是让其中一个线程(在我的代码中,它是主线程,起始线程)允许玩家在tic-tac趾板上选择一个空格,当他们单击它时,它将更改图标,然后AI将等待1秒,然后从我创建的第二个线程播放
不幸的是,每当我调用
ait.sleep(1000)
(ait
是我的线程名)时,两个线程都会等待1秒才能完成执行。有人能告诉我为什么睡眠一个线程会停止我的整个执行吗?如果你想让ait
线程睡眠,那么就让该线程睡眠。一条线“伸入”另一条线并在低水平上推动它的设计从根本上被打破。你为每一个线程编写代码,所以写代码时首先要做你想让它做的事情,这样你就不需要从外部接触它
哪个更有意义,厨房里的人知道如何做早餐,还是卧室里的人大声喊叫,指导他们做早餐的每一步?当然,你可以告诉他们做早餐。但你肯定不会把每一步都放在一个低水平上
有人能告诉我为什么睡一根线会让我的整个生活停止吗
执行
为了更好地解释您的Swing GUI是在它自己的特殊线程上创建的,与运行main()
和其他代码的线程不同,这是通过在SwingUtilities.invokexx
块中创建Swing组件来完成的(即使您没有这样做,您的GUI也将在一个名为的线程上运行)。现在,如果您在事件调度线程
(或在同一线程
)上调用sleep
,它将等待对线程.sleep
的调用完成。现在,由于所有Swing事件都在EDT上处理,我们通过调用sleep(..)
暂停其执行,从而暂停处理UI事件,因此GUI被冻结(直到sleep(..)
返回)
您不应该使用Thread.sleep(..)
on(或任何Thread
中的sleep将导致不必要的执行阻塞),因为这将导致UI看起来冻结
这是一个很好的例子,它准确地演示了调用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();
- ,然后使用
(但这是任何情况下的最后一个选项)Thread.sleep(intmilis)
Swing Timer
/SwingWorker
仅在Java 1.6中添加,然而,TimerTask
和Thread
在Java 1.3和JDK 1中出现的时间更长,因此,您甚至可以使用上述两种方法中的任何一种,并在SwingUtilities/EventQueue#invokeXX
块中包装创建/操作Swing组件的调用;这就是过去的做法:P是一种静态方法。通过引用任何给定的
线程
调用它只是一种方便的形式
因此,对
sleep
的任何调用实际上都是在当前线程
上调用sleep
,我怀疑这就是您案例中的事件线程。事件线程上的休眠/阻塞将出现被锁定的外观。线程。休眠是一种静态方法,可导致当前执行的线程在指定的时间内休眠。Java语法允许您通过变量调用静态方法,但编译器只是使用该变量的编译时类型来确定要调用的方法,即
Thread ait = null;
ait.sleep(1000); // calls Thread.sleep(1000), causing current thread to sleep.
// In particular, does *not* NPE
您还提到了wait()
-虽然这是一个实例方法而不是静态方法,但它仍然会导致当前线程进行等待(ait.wait(1000)
将导致当前线程等待最多1秒,或者直到另一个线程调用ait.notifyAll()
)
有一种Thread.suspend()
及其对应的resume()
是在Java的早期引入的,它允许一个线程控制另一个线程,但很快就被弃用了,因为它们天生就容易死锁。如果您想让一个线程“控制”另一个线程,建议使用的模式是协同操作,即使用某种共享标志,线程A设置线程B读取,并让B根据该标志将自己发送到睡眠状态:
volatile boolean threadBShouldRun = true;
// Thread B
while(true) {
if(threadBShouldRun) {
// do some stuff
} else {
Thread.sleep(1000);
}
}
// Thread A
if(someCondition) {
threadBShouldRun = false;
}
但是使用java.util.concurrent
包中的工具通常更容易,也不容易出错。正确地执行多线程比表面上看起来要困难得多。您是从ait
线程内部还是从其他线程调用ait.sleep(1000)
?是的,我是从ait内部调用sleep(1000),而不是从volatile
调用AtomicBoolean
?@DavidKroukamp这将是另一个选项是的,虽然对于布尔人来说,一个线程只是设置,另一个线程只是获取,但它并不能在普通的volatile上为你买任何东西。当然,如果你真的需要原子getAndSet
或compareAndSet
操作,那就不一样了。非常感谢你,Swing定时器工作得很好,我的程序运行时没有太多的混乱。再次感谢