Параллелизм в Java - дождитесь завершения выполнения

1

Поэтому я в настоящее время занимаюсь некоторой работой с Multi-Threading в Java, и я довольно зациклен на, скорее всего, простой вещи.

В настоящее время у меня есть JButton, который при нажатии вызывает метод следующим образом:

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

а затем занимает около 10-30 секунд. Однако в течение этого времени все еще можно повторно щелкнуть JButton так, чтобы он зависел от того, как отображается информация.

То, что я хочу сделать, - это время, когда этот конкретный поток "живой", отключите кнопку, чтобы ее больше не было возможно щелкнуть (и, таким образом, активировать этот поток, как только он уже будет). Как только поток закончен, я хочу снова включить кнопку.

Код кнопки выглядит просто так:

button.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent evt) {
                if (evt.getClickCount() == 1) {
                        try {
                            clickTest();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                }
            }
        });
  • 3
    Обычно, когда вы хотите дождаться завершения потока, вы должны вызвать для него join () . Хотя это будет препятствовать обновлению вашего графического интерфейса в течение всего потока.
  • 0
    Да, я тоже это заметил. Пробовал метод join () ранее, и как вы сказали; это препятствует обновлению GUI. Мой код обновляет GUI все время одновременно, и у меня одновременно работает несколько таких методов.
Показать ещё 2 комментария
Теги:
multithreading
concurrency

3 ответа

2

Отключите кнопку перед запуском потока. В потоке в конце разместите событие, которое будет повторно активировать кнопку (с помощью invokeLater).

Вам также может потребоваться вариант отмены, но это отдельный вопрос.

0

Хорошим решением для этого является использование стеклянной панели для захвата всех событий и прекращения их распространения на любой из ваших элементов интерфейса на панели под стеклянным стеклом. Конечно, хотя у вас есть только один или два, вы можете называть их setEnabled(false) вручную, но стеклянные панели дают вам больше гибкости, вам никогда не придется беспокоиться о добавлении нового элемента в свой пользовательский интерфейс и забыть отключить его во время фона обработка.

Наверное, слишком много для одной кнопки.

Другая, не связанная с этим вещь, которую вы должны учитывать, - это использование Executor s вместо запуска потоков для фоновых задач. Это приводит к более чистым и масштабируемым кодам.

  • 0
    Есть более одного, хотя. Это всего лишь пример из всей картины. Все они будут служить одной цели и делать одно и то же, только с разными функциями. Я посмотрю на это, хотя! Благодарю.
0

Попробуйте следующее:

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();
                    }
            }
        }
    });

Затем измените метод run вашего класса " Happiness ":

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.

}
  • 0
    Это не работает! : / Сама кнопка становится серой, но она все равно реагирует на то, что я нажимаю на нее.
  • 0
    оо ... ты уверен? setEnabled(false) должен отключить все нажатия на кнопку. Какая у вас ОС?
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню