对单个线程使用sleep()

Har*_*per 3 java swing multithreading event-dispatch-thread thread-sleep

我对java很新,并开始使用不同的线程来使用wait()sleep()在我的代码的一部分上运行其他代码.

对于这个项目,我使用JFramejavax.swing.*java.awt.*进口.我想要做的是让其中一个线程(在我的代码中它是主要的,起始线程)允许玩家在tic tac toe board上选择一个空间,当他们点击它时,它将改变图标,并且然后AI将等待1秒钟,然后从我创建的第二个线程回放.

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

Dav*_*amp 14

任何人都可以告诉我为什么睡一个线程会阻止我的整个执行

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

你不应该使用Thread.sleep(..)on Event Dispatch Thread(或任何Thread睡眠都会阻止不必要的执行阻塞),因为这会导致UI看起来被冻结.

是一个很好的例子,它准确地说明了这种不必要的行为是由Thread.sleep(..)GUI的EDT 调用引起的.

而是使用:

  • 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();
    
    Run Code Online (Sandbox Code Playgroud)
  • 摇摆工人

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

  • 的TimerTask

  • 线程,然后你会使用Thread.sleep(int milis)(但在任何情况下都是IMO的最后一个选项)

UPDATE

Swing Timer/ SwingWorker只是在Java 1.6中添加了,TimerTask并且Thread已经存在了很多正弦Java 1.3和JDK 1,因此您甚至可以使用上述两种方法中的任何一种来封装在SwingUtilities/EventQueue#invokeXX块中创建/操作Swing组件的调用; 这就是以往的方式:P