Gui blocked when starting Thread from button click

2019-01-29 00:45发布

问题:

This may be a basic question but one that I am stuck on.

I would like some more understanding on why the GUI is blocked when I start a new thread(runnable) from a button click event? and how do I overcome that? What am I doing wrong?

The code below starts a new thread when it is clicked, however I would like to change the background color of a textbox when that button is clicked but I am unable to do that, also the main ui is unresponsive whilst that thread is running, I believed that I was implementing it correctly by starting a new thread so as to NOT block the main ui but I must have missed something out as this obviously not desired behaviour.

Code:

private void startButtonEvent(ActionEvent evt) {

         ntmStatusText.setBackground(Color.green);// textbackground I want to change

        //Start Ntm Thread
         Thread thread = new Thread(new NtmThread());
           thread.start();

           while(thread.isAlive()){

               System.out.println("thread still working");

           }
           System.out.println("thread stopped");

    }

How do I stop my Ui from becoming unresponsive when running threads?

回答1:

while(thread.isAlive()){ is a blocking method, it will stop the Event Dispatching Thread until Thread.isAlive becomes false, this prevents it from been able to process new events that are been added to the event queue, including paint requests

This occurs because Swing is a single threaded environment, meaning that there is a single thread responsible for process all events coming into the program. This is handled by the Event Dispatching Thread.

All user generated events are managed within the EDT (that is, you actionPerformed method, is called within the context of the EDT)

Concurrency in Swing

You eaither theen to provide a call back functionality to your NtmThread or consider using a SwingWorker and attaching a PropertyChanegListener to it a monitor for the property state and check that the SwingWorkers state has changed to DONE

See Worker Threads and SwingWorker for more details

As an example: How to use jProgress bar for ProcessBuilder process?



回答2:

You have created a new thread but you are using current thread to check if the created thread is alive or not while(thread.isAlive()){.
So the current thread can never come out of the loop untill thread you created is not stopped.
And your this current thread was responsible for doing all gui work, but you made it stuck, that is why your GUI is blocked.