Java 生成单独的线程时,Swing将冻结

Java 生成单独的线程时,Swing将冻结,java,swing,Java,Swing,为什么这段代码会冻结我的Swing应用程序?Swing组件与InfiniteLop线程位于单独的线程中。如果我在每次打印之前在run()方法中引入sleep,那么程序工作正常。有人有线索吗 public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); // <

为什么这段代码会冻结我的Swing应用程序?Swing组件与InfiniteLop线程位于单独的线程中。如果我在每次打印之前在run()方法中引入sleep,那么程序工作正常。有人有线索吗

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI(); // <-- creates the swing frame and component
        }
    });

    Thread t = new Thread(new InfiniteLoop()); 
    t.start();
}

public class InfiniteLoop implements Runnable
{
    private static Logger logger = Logger.getLogger(InfiniteLoop.class);
    public void run()
    {
         while(true)
         {
              log.info("test");
         }
    }
}
publicstaticvoidmain(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
公开募捐{

createAndShowGUI();//这里的答案与Java的线程调度实现有关(或者更确切地说,与您的平台的Java线程调度实现的细节有关)。大多数Java线程实现最终运行的是给定的线程(以给定的优先级)直到线程进入等待状态,然后该优先级的下一个线程运行,等等。请注意,JVM规范没有指定确切的行为——这由JVM实现者决定

<> P>而不是将睡眠插入到工作线程中,你可能想考虑删除工作线程的优先级。睡眠线程将工作,但这是一个麻烦,要记住去做它,它迫使工作线程需要更长的时间来做事情,否则就必须做。如果你结束插入睡眠呼叫,做它0毫秒。(这足以释放线程,但如果没有其他活动线程,则应立即返回执行)

这是一个描述这一点的例子

作为一种潜在的细化:invokeLater()调用可能会将可运行线程放入一个永远没有机会出列的队列中,因为您的后台线程占用了所有CPU。一个有趣的实验是将后台线程的启动移到可运行线程中-这将使EDT有机会在您的后台线程开始消耗CPU之前进行初始化

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI(); // <-- creates the swing frame and component

            Thread t = new Thread(new InfiniteLoop()); 
            t.start();
        }
    });

}
publicstaticvoidmain(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
公开募捐{

createAndShowGUI();//为了更快地获得更好的帮助,发布一个@andrewhompson-只是好奇-这不是他所做的吗?@KevinDay否。运行时问题的SSCE应该是一个可以复制、粘贴和编译的单一源文件(0个更改),运行并显示问题。事实上,我们有两个类的一部分没有导入->不是SSCCE.ok-足够公平。这个例子足以解释这个行为,但我同意,如果我真的要尝试这个,我会额外花费30或40秒,这可能就是我花费时间的区别或者不是。我只是很高兴这个问题问得这么好,可以马上得到回答!干杯。这个答案比我的好。1+给Kevin,我将删除我较弱的答案。呸-有很多方法可以剥那只猫的皮。值得一提的是,我很难找到默认的EDT线程优先级是什么,也找不到合适的答案引用说明了这一点。如果EDT没有以更高的优先级运行,我实际上会有点惊讶,但是放弃工作线程的优先级似乎是最好的第一步。我们可能会发现我的答案(虽然在技术上是准确的)这对问题的细节很重要。非常糟糕的答案,真的,永远不要,永远不要从invokeLater启动线程,这是一种杀死EDT的方法,你怎么知道线程内部是什么,也不知道Swing GUI可能会等待线程结束,aaachhin在GUI还不可见的情况下(EDT不会在GUi可见的那一刻结束)然后是first sleep()或wait()阻止Swing的可见性Container@mKorbel从EDT启动
线程
不会阻止EDT。否则,您如何从某个用户操作启动
SwingWorker
?在这种情况下,您还可以从EDT启动一个新的
线程
,这很好
public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            Thread t = new Thread(new InfiniteLoop()); 
            t.start();

            createAndShowGUI(); // <-- creates the swing frame and component
        }
    });

}