Многопоточность и поведение пользовательского интерфейса - PullRequest
0 голосов
/ 13 марта 2012

У меня есть приложение Java, в котором я использую поток. Мой поток запускается каждые 20 секунд, но когда он запускается, он как бы блокирует пользовательский интерфейс ... i. е. всякий раз, когда поток работает, и пользователь нажимает кнопку на любом элементе пользовательского интерфейса, он иногда не отвечает.

Может кто-нибудь сказать мне решение этой проблемы.

Ответы [ 3 ]

3 голосов
/ 13 марта 2012

в java Swing, любое изменение, внесенное в состояние пользовательского интерфейса, должно быть сделано в одном ранее существующем потоке, называемом EDT (поток-диспетчер событий).

, если это не так, вы обычноиспытать странные глюки / зависания.Одним из наиболее распространенных симптомов является то, что часть пользовательского интерфейса становится серой (за исключением версии Java 1.6, где пользовательский интерфейс по-прежнему окрашен, как и раньше, но не отвечает).

хороший способ - использовать выделенный методчтобы поставить в очередь свои изменения в пользовательском интерфейсе в EDT:

SwingUtilities.invokeLater(Runnable toRunInEDT);

обратите внимание, что если вы вызываете invokeLater, runnable выполняется после того, как все текущие в очереди события были отправлены.это означает, что следующая строка кода может быть выполнена перед кодом в исполняемом файле.существует также синхронная версия (которая не должна выполняться из EDT):

SwingUtilities.invokeAndWait(Runnable toRunInEDT);
3 голосов
/ 13 марта 2012

Несколько дополнительных советов, в дополнение к тому, что сказал Эдралзар:

Вы можете использовать вспомогательный метод SwingUtilities.isEventDispatchThread(), чтобы проверить, действительно ли код выполняется в потоке диспетчеризации событий. И, как сказал edralzar, любой код, который создает компоненты GUI, изменяет состояние компонентов GUI или считывает состояние компонентов GUI, должен выполняться в потоке диспетчеризации событий.

Однако следует учитывать и то, что код , работающий на EDT, должен иметь возможность довольно быстро выполняться . Таким образом, вы не можете просто решить проблемы, запустив все в потоке отправки событий. Если вы сделаете следующее, ваш графический интерфейс будет заморожен на пять секунд:

SwingUtilities.invokeLater(new Runnable(){
        public void run(){
            try{
                Thread.currentThread().sleep(5000);
            }catch(InterruptedException e){
                //Ignored in this example
            }
        }
    });

Почему он заморожен? Поскольку все события GUI и обновления GUI выполняются в EDT, и если EDT спит в течение 5000 миллисекунд, обновления GUI в течение этого времени не могут быть выполнены.

Эта статья может быть интересным чтением.

2 голосов
/ 13 марта 2012

Похоже, что поток, на который вы ссылаетесь (который запускается каждые 20 секунд), также является потоком, который управляет пользовательским интерфейсом.

Решение состоит в том, чтобы разделить два процесса на разные потоки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...