使用睡眠()为单个线程

我相当新的Java,并开始进入使用不同的线程,以便对我的代码的一部分使用wait()sleep() ,并让其他人仍然运行。

对于这个项目,我正在使用带有javax.swing.*java.awt.* JFrame导入。 我想要做的是有一个线程(在我的代码中,它是主要的起始线程)允许玩家在井字棋板上select一个空间,当他们点击它时,它会改变图标,那么AI会等待1秒,然后再从我创build的第二个线程回放。

不幸的是,每当我调用ait.sleep(1000)ait是我的线程名)时,两个线程在完成执行之前等待1秒钟。 谁能告诉我为什么睡一个线程是停止我的整个执行?

谁能告诉我为什么睡一个线程是停止我的整个执行

为了更好地解释你的Swing GUI是在它自己的特殊线程上创build的,它独立于main()和其他代码的运行,这是通过在SwingUtilities.invokeXXX块中创buildSwing组件完成的(即使你没有这样做GUI将在称为初始线程的单个线程上运行)。 现在,如果你只是在Event Dispatch Thread (或者在同一个Thread )调用sleep ,它将等待Thread.sleep的调用完成。 现在因为所有的Swing事件都是在EDT上处理的,所以我们通过调用sleep(..)暂停它的执行,从而暂停处理UI事件,因此GUI被冻结(直到sleep(..)返回)。

你不应该使用Thread.sleep(..)Event Dispatch Thread (或任何Thread睡眠会引起不必要的执行阻塞),因为这将导致UI似乎冻结。

下面是一个很好的例子,它演示了在EDT的EDT上调用Thread.sleep(..)导致的不需要的行为。

而是使用:

  • Swing Timer例如:

     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(); 
  • 摇摆工人

或者如果没有创build/修改Swing组件:

  • 的TimerTask

  • 线程 ,你会然后使用Thread.sleep(int milis) (但是这是最后一个选项在任何情况下国际海事组织)

UPDATE

Swing Timer / SwingWorker只是在Java 1.6中添加的,然而, TimerTaskThread已经有了更多的正弦Java 1.3和JDK 1,所以你甚至可以使用上述两种方法中的任何一种,并且可以创build/操作Swing组件在SwingUtilities/EventQueue#invokeXX块; 多数民众赞成曾经的做法:P

Thread.sleep是一个静态方法。 通过任何给定的Thread引用它的调用只是一种方便的forms。

因此,任何sleep调用都是在当前Thread上调用sleep ,我怀疑这是您的情况下的事件线程。 在事件线程上的睡眠/阻塞将会出现被锁住的现象。

如果你想让ait线程进入睡眠状态,那么ait 这个线程编码到睡眠状态。 一个线程“进入”另一个线程并将其推到低位的devise从根本上被打破了。 你为每一个线程编写代码,所以编写它来做你想做的事情,所以你不会从外面伸手去做。

哪一个更有意义,让厨房里的人知道如何做早餐或卧室里的人喊叫,指导他们去做早餐的每一步? 当然,你可以告诉他们做早餐。 但是你绝对不要把每个步骤都指向低级别。

Thread.sleep是一个静态方法,它导致当前正在执行的线程在指定的时间内hibernate。 Java语法允许你通过一个variables来调用一个静态方法,但是编译器只是使用该variables的编译时types来决定调用哪个方法,即

 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包中的工具通常更容易,也更不容易出错。 做multithreading的权利比表面上看起来要困难得多。

Interesting Posts