Java Thread.sleep是如何工作的?

Java Thread.sleep是如何工作的?,java,multithreading,swing,sleep,event-dispatch-thread,Java,Multithreading,Swing,Sleep,Event Dispatch Thread,我制作了一个程序,可以不时设置按钮的setEnable。Thread.sleep()在另一个类中。代码如下: import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Try extends JFrame implements ActionListener{ JButton n1 = new JButton("1"); JButton n2 = new JButton("2"); JButton

我制作了一个程序,可以不时设置按钮的
setEnable
Thread.sleep()
在另一个类中。代码如下:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Try extends JFrame implements ActionListener{
JButton n1 = new JButton("1");
JButton n2 = new JButton("2");
JButton n3 = new JButton("3");
JButton show = new JButton("Show");

{
show.addActionListener(this);
n1.setEnabled(false);
n2.setEnabled(false);
n3.setEnabled(false);

}

public Try(){
  super("Try");
  setVisible(true);
  setSize(500, 200);
  setLayout(new GridLayout(1, 4));
  add(n1);
  add(n2);
  add(n3);
  add(show);
}  

public void actionPerformed(ActionEvent a) {
Object clicked = a.getSource();
if(show == clicked){
new EasyLevel1().start();
}
}

  class EasyLevel1 extends Thread {
    public void run() {      
        try {
            n1.setEnabled(true);
            Thread.sleep(1000);
            n1.setEnabled(false);
            n2.setEnabled(true);
            Thread.sleep(1000);
            n2.setEnabled(false);
            n3.setEnabled(true);
            Thread.sleep(1000);
            n3.setEnabled(false);    
        } catch (InterruptedException e){
        }
        }
      }

    public static void main(String[] args){
      Try frame = new Try();
      frame.setVisible(true);
    }
    }
但是,当我将它放在类中的
actionListener
上时:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Try extends JFrame implements ActionListener{
JButton n1 = new JButton("1");
JButton n2 = new JButton("2");
JButton n3 = new JButton("3");
JButton show = new JButton("Show");

{
show.addActionListener(this);
n1.setEnabled(false);
n2.setEnabled(false);
n3.setEnabled(false);

}

public Try(){
  super("Try");
  setVisible(true);
  setSize(500, 200);
  setLayout(new GridLayout(1, 4));
  add(n1);
  add(n2);
  add(n3);
  add(show);
}  

public void actionPerformed(ActionEvent a) {
Object clicked = a.getSource();
if(show == clicked){
            try {n1.setEnabled(true);
            Thread.sleep(1000);
            n1.setEnabled(false);
            n2.setEnabled(true);
            Thread.sleep(1000);
            n2.setEnabled(false);
            n3.setEnabled(true);
            Thread.sleep(1000);
            n3.setEnabled(false);
            } catch (InterruptedException e){}
}
}

public static void main(String[] args){
  Try frame = new Try();
  frame.setVisible(true);
}
}
它冻结了我的整个程序,基于这个例子,我知道线程睡眠应该在另一个线程中运行,以阻止当前类冻结。但是我期望新的thread.sleep with仍然冻结它的操作,就像它仍然会执行上面的代码一样,但是按钮会响应,因为它在另一个线程中。但令人惊讶的是,它做到了我希望它做的事情,它没有像第一个程序那样立即将所有内容设置为禁用。

Thread.sleep()
使当前线程暂停。您正在Swing事件中执行的
操作中运行它。所有Swing操作都在一个线程EDT中完成。使用Thread.sleep()暂停时,Swing无法处理任何其他事件,因为您尚未从actionPerformed侦听器返回。因此,GUI冻结(不是整个应用程序,只是GUI)

一般来说,因此在Swing事件中执行长时间运行的操作是不好的做法。对于您试图执行的操作,最好的替代方法是使用Swing计时器。

Thread.sleep()
使当前线程暂停。您正在Swing事件中执行的
操作中运行它。所有Swing操作都在一个线程EDT中完成。使用Thread.sleep()暂停时,Swing无法处理任何其他事件,因为您尚未从actionPerformed侦听器返回。因此,GUI冻结(不是整个应用程序,只是GUI)


一般来说,因此在Swing事件中执行长时间运行的操作是不好的做法。对于您尝试执行的操作,最好的替代方法是使用Swing计时器。

线程。睡眠将导致执行调用的线程在指定时间内睡眠(或直到线程中断)。当您在
actionPerformed
方法中调用它时,它会导致UI线程休眠。这就是你的程序被锁定的原因


您应该启动一个单独的线程,该线程将单步执行您想在其间睡眠时进行的各种调用。或者(在我看来,更好的方法是)你可以用它来做你想做的事情。

线程。sleep
将导致执行调用的线程在指定的时间内睡眠(或者直到线程被中断)。当您在
actionPerformed
方法中调用它时,它会导致UI线程休眠。这就是你的程序被锁定的原因


您应该启动一个单独的线程,该线程将单步执行您想在其间睡眠时进行的各种调用。或者(在我看来,更好的方法是)你可以用它来做你想做的事情。

发生的事情是在第二个示例
线程中。睡眠
阻止了
EDT
,因此没有进一步的UI更新发生。相反,在第一个示例中,您在
线程中调用
sleep
,因此不会发生“冻结”。对于这样的任务,最好使用。

发生的情况是,在第二个示例中,
线程。睡眠
会阻止
EDT
,因此不会发生进一步的UI更新。相反,在第一个示例中,您在
线程中调用
sleep
,因此不会发生“冻结”。对于这样的任务,最好使用。

谢谢,它确实让我头脑清醒了很多,所以它确实在第二个示例中做了我想要做的事情,但是,当线程睡眠时,它也睡眠了我的gui代码,所以它“因为我的gui也在睡眠”并且在睡眠后变得响应,因为它不再睡眠。是吗?@JerlyTuazon-没错。如果您使用swing计时器安排各种
setEnabled
调用,您的gui将不会锁定。我有一个问题要问,但它与“冻结”无关,但它涉及到thread.sleep。为什么thread.sleep总是有中断异常问题?我的意思是,他们已经解释为当睡眠受到干扰或其他什么的时候。但我试着只留下一行由线程及其线程执行。sleep,但就我所知,它仍然显示InterruptedException。sleep没有过早关闭或受到干扰?@JerlyTuazon-有时,在多线程应用程序中,你希望一个线程向另一个线程发出信号,表示它应该停止正在执行的操作。信令线程可以调用另一个线程的
interrupt()。应写入另一个线程以检查其中断标志(使用
isInterrupted()
)。然而,当它睡觉的时候,它显然不能这样做。但是,当调用休眠线程的
interrupt()
方法时,
sleep()
调用会以
InterruptedException
提前退出。这不是一个“问题”--这是一个功能:您刚刚被(程序中的另一个线程)告知退出。@JerlyTuazon在您的特定应用程序中使用此“中断功能”的一种方式是处理用户在(当前线程)级联按钮工作期间再次单击“显示”的情况。如果您希望级联“重置”,那么中断当前线程的工作以便在新线程中重新启动它可能是有意义的。当然,这更多的是一个概念性思维练习;当您迁移到Swing timer时,我相信有一个计时器停止功能。谢谢,它确实让我头脑清醒了很多,所以它确实在第二个示例中实现了我想要的功能,但是,当线程睡眠时,它也睡眠了我的gui代码,因此它“frooze,因为我的gui也在睡眠”,并且在睡眠后变得响应,因为它不再睡眠。是吗?@JerlyTuazon-没错。如果您使用swing定时器来安排各种
setEnabled
调用,您的gui将不会锁定。我有一个问题要问,但它与“冻结”无关,但它是inv