简体   繁体   中英

Concurrency in Java - wait for execution to be finished

So I am currently doing some work with Multi-Threading in Java and I'm pretty stuck on a, most likely, simple thing.

I currently have a JButton that, when pressed invokes the method as follows:

private void clickTest() throws InterruptedException{
    statOrganizer.incrementHappiness();
    Thread t = new Thread(new Happiness(workspaceHappy));
    t.start();
}

and then takes around 10-30 seconds to complete. During this time however, it is still possible to re-click the JButton so that it messes with how the information is displayed.

What I want to do is during the time this particular thread is "alive", disable the button so that it is no longer possible to click it(and thus activate this thread once it's already going). Once the thread is finished, I want to re-enable the button again.

The button code just looks like this

button.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent evt) {
                if (evt.getClickCount() == 1) {
                        try {
                            clickTest();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                }
            }
        });

Disable the button right before starting the thread. In the thread, at the end, post an event that would re-enable the button (using invokeLater).

You may also need a cancel option, but that's a separate question.

The nice solution for this is to use a glass pane to capture all events and stopping them from propagating to any of your UI elements on the panel under the glass pane. Of course while you only have one or two, you can call setEnabled(false) on them manually but glass panes give you more flexibility, you'll never have to worry about adding a new element to your UI and forgetting to disable it during background processing.

Probably an overkill for one button though.

Another, unrelated thing you should consider is the use of Executor s instead of launching threads for background tasks. It results in cleaner and more scalable code.

Try the following:

button.addMouseListener(new MouseAdapter() {
        public void mouseClicked(MouseEvent evt) {
            if (evt.getClickCount() == 1) {
                    try {
                        clickTest();
                        button.setEnabled(false);//this assume 'button' is final
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
            }
        }
    });

Then, modify the run method of your Happiness class:

public void run()
{

 //your processing code here
 ...

 button.setEnabled(true);
 //reference to button can be passed in constructor of Happiness
 // or access using getter, ... This really depend on your implementation.

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM