Java 虽然我们从另一个线程更新GUI组件,但不面临任何GUI冻结问题

Java 虽然我们从另一个线程更新GUI组件,但不面临任何GUI冻结问题,java,multithreading,swing,swingworker,Java,Multithreading,Swing,Swingworker,作为学习Java swing上SwingWorker的一部分,我创建了一个简单的程序,其中一个不同的线程(EDT除外)正在执行一些后台任务,一旦完成,该线程将更新GUI组件(JTextArea) 据我所知,如果我们尝试从外部线程(而不是EDT)更新GUI组件,则UI可能会冻结。但这并没有发生。我真的很想创建这种情况(冻结UI),以便更好地理解它。下面是我试过的代码。有人能帮我说一下我需要对代码做些什么,这样UI就会冻结 App.java MainFrame.java MyTestThread.j

作为学习Java swing上SwingWorker的一部分,我创建了一个简单的程序,其中一个不同的线程(EDT除外)正在执行一些后台任务,一旦完成,该线程将更新GUI组件(JTextArea)

据我所知,如果我们尝试从外部线程(而不是EDT)更新GUI组件,则UI可能会冻结。但这并没有发生。我真的很想创建这种情况(冻结UI),以便更好地理解它。下面是我试过的代码。有人能帮我说一下我需要对代码做些什么,这样UI就会冻结

App.java MainFrame.java MyTestThread.java
import javax.swing.JTextArea;
公共类MyTestThread扩展了线程{
私有整数i=0;
私人JTextArea txtAreaRef;
公共空间设置tNREF(JText区域ta){
this.txtAreaRef=ta;
}
公开募捐{
而(i<500000){
试一试{
txtAreaRef.append(“测试”+i+“\n”);
i=i+1;
睡眠(2000年);
}catch(InterruptedException e){System.out.println(e.getMessage());
e、 printStackTrace();
}
}
}
}

我不知道这些信息是从哪里来的,但在EDT之外调用GUI更新不会导致UI冻结

如果您想产生冻结,请尝试在EDT内创建一个无限循环,如下所示

这将导致UI永久冻结

    public void actionPerformed(ActionEvent e) {

            //MyTestThread extThr = new MyTestThread();
            //extThr.setBtnRef(txtArea);
            //extThr.start();

            while(true) {}
    }

什么?你从哪里得到这些信息的?在EDT之外更新GUI组件不会导致GUI冻结。“据我所知,如果我们尝试从EDT以外的外部线程更新GUI组件,则UI可能会冻结。”-不,如果在EDT之外更新UI,则可能会导致油漆变脏和其他线程问题(如竞争条件)。如果要尝试查看“UI冻结”,请删除thread@MadProgrammer,因此,SwingWorker类适用于在后台运行并在线程之间通信的长时间运行任务-EDT和非EDT?
SwingWorker#doInBackground
将在EDT之外执行,它的
process
方法将在EDTGUI中执行冻结可能是由于EDT上的长进程(如睡眠)而不是关闭它造成的。因此,SwingWorker类适用于在后台运行的长时间运行任务以及线程之间的通信-EDT和非EDT?
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class MainFrame extends JFrame implements ActionListener {

    private JButton btn,btn2;
    private JTextArea txtArea;

    public MainFrame() {
        super("Hello World");

        setLayout(new BorderLayout());
        btn = new JButton("Click Me!");
        btn2 = new JButton("Click Me New!");
        txtArea = new JTextArea();
        btn.addActionListener(this);


        add(txtArea,BorderLayout.CENTER);
        add(btn,BorderLayout.SOUTH);
        add(btn2,BorderLayout.NORTH);

        setSize(600,800);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {

        MyTestThread extThr = new MyTestThread();
        extThr.setBtnRef(txtArea);
        extThr.start();
    }

}
import javax.swing.JTextArea;

public class MyTestThread extends Thread {

    private int i = 0;
    private JTextArea txtAreaRef;

    public void setBtnRef(JTextArea ta) {
        this.txtAreaRef = ta;
    }

    public void run() {

        while (i < 500000) {

            try {
                txtAreaRef.append("test"+i+"\n");
                i=i+1;
                sleep(2000);
            } catch (InterruptedException e) {System.out.println(e.getMessage());
                e.printStackTrace();
            }
        }

    }

}
    public void actionPerformed(ActionEvent e) {

            //MyTestThread extThr = new MyTestThread();
            //extThr.setBtnRef(txtArea);
            //extThr.start();

            while(true) {}
    }