Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 对单个线程使用sleep()_Java_Multithreading_Swing_Event Dispatch Thread_Thread Sleep - Fatal编程技术网

Java 对单个线程使用sleep()

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秒才

我对java相当陌生,我开始使用不同的线程,以便在代码的一部分上使用
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定时器工作得很好,我的程序运行时没有太多的混乱。再次感谢