主线程冻结所有其他线程,包括 java gui 线程

Posted

技术标签:

【中文标题】主线程冻结所有其他线程,包括 java gui 线程【英文标题】:Main Thread freezes all other threads inclusive java gui thread 【发布时间】:2016-04-16 21:38:58 【问题描述】:

注意:我工作了很多时间并研究了谷歌和 ***,但我找不到答案。

我在 JDialog 中使用 Thread.sleep(),它会冻结所有其他 JDialog、JFrame 和线程。

我的示例代码:

public Guitest()

    setSize(300,300);


    // create a JDialog that make guitest wait
    MyDialog dlg = new MyDialog();
    dlg.setSize(100,100);
    dlg.setVisible(true);

    while(dlg.isWait())
    
        try
        
            Thread.sleep(1000);
         catch (InterruptedException ex)
        
            Logger.getLogger(Guitest.class.getName()).log(Level.SEVERE, null, ex);
        
        System.out.println("waiting mydialog");
    





class MyDialog extends JDialog

    boolean wait = true;
    JButton btn = new JButton("OK");

    public MyDialog()
    
        setSize(50,50);

        btn.addActionListener(new ActionListener()
        

            @Override
            public void actionPerformed(ActionEvent e)
            
                wait=false;
            
        );
        add(btn);
    

    public boolean isWait()
    
        return wait;
    

在这种情况下,JDialog 无法正确显示:

inccorect appear jdialog

但它必须是这样的:

true appear jdialog

我该如何解决这个问题。我想让主线程等待另一个线程。有人可以更正我的示例代码或与这种情况分享示例代码。

【问题讨论】:

【参考方案1】:

恕我直言,您似乎只有一个正在运行的线程。首先,我们绘制 JDialog,之后,由于等待标志,您将主线程休眠。 IE。你不能执行你的按钮动作监听器,因此你不能唤醒你的线程。

希望对理解有所帮助。

【讨论】:

我不这么认为,你必须自己实现它。我找到了这个帖子:***.com/questions/20269083/… 谢谢你的回答,我明白了。我应该在Java中学习很多东西。 :)【参考方案2】:

Thread.Sleep() 只是休眠当前线程(即阻止它执行任何操作,例如重绘、处理点击等),在您的情况下是 UI thread

您需要使用工作线程。任何需要完成的可能需要花费大量时间的主要工作都需要在其自己的线程中完成,这就是您想要休眠的线程。它目前与 UI 组件一起运行,因此这就是您看到它们冻结的原因。

swinghttp://docs.oracle.com/javase/tutorial/uiswing/concurrency/ 的并发文档是一个很好的参考

以下内容也可能有用:

http://java.sun.com/developer/technicalArticles/Threads/swing/ http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html

【讨论】:

它们都在UI thread 上运行,而Thread.sleep() 正在锁定它。当在 worker thread 上执行时,它会产生不同的影响,但它目前与 UI 组件一起运行,这就是您看到它们被锁定的原因!

以上是关于主线程冻结所有其他线程,包括 java gui 线程的主要内容,如果未能解决你的问题,请参考以下文章

即使我在单独的线程中运行,QT GUI 也会冻结

Tkinter:如何使用线程来防止主事件循环“冻结”

子线程中的 waitForReadyRead() 冻结 GUI 线程

避免多线程操作中的 GUI 冻结

有没有办法暂停Java中主要线程的所有线程?

Tkinter GUI 冻结 - 解除阻塞/线程的提示?