2010-04-19 3 views
3

Я знаю, что эта проблема вызвана спящим или ожидающим вызовом основного потока, и что ответ на вопрос о том, как решить эту проблему, заключается в том, чтобы поместить метод в отдельный нить, а затем заставьте эту нить спать. Но код беспорядок и на самом деле не имеет времени, чтобы разобраться в нем и разделить его на отдельные потоки, и было интересно, есть ли другой способ сделать это? Даже если это не самая чистая или наиболее распространенная практика для работы с графическими интерфейсами. Мне нужно всего лишь секундную паузу из метода.Java GUI, нужно приостановить метод без зависания GUI, а также

ответ

8

Вы не можете сделать это, не создавая отдельный поток. Создание потока на Java просто. Единственное, на что нужно обратить внимание, это то, что вы можете касаться только пользовательского интерфейса через основной поток. По этой причине вам нужно использовать что-то вроде SwingUtilities.invokeLater().

+0

Или, если ему нужно пойти другим путем, он мог бы использовать javax.swing.SwingWorker, чтобы переместить метод выключения поток отправки событий (EDT). – ILMTitan

+0

Ссылка не работает. – HewwoCraziness

1

Невозможно спать в потоке событий, а не вызывать зависание GUI. Однако в Swing поток событий создается и управляется за кулисами - основной поток (тот, который исходит из метода main()) - это не поток событий.

Итак, вы можете спокойно спать в своей основной теме.

0

Использование отдельной темы для кода является вашим единственным решением. Каждое действие, начинающееся потоком Swing, должно быть делегировано отдельному потоку, если оно иначе блокирует GUI.

-6

И где бы объявить эту тему. Пожалуйста, имейте в виду, что любая ссылка на функцию, которая содержит спящий поток, приведет к приостановке основного потока. Потому что основному потоку придется подождать, пока вспомогательный поток не остановится.

Реальность заключается в том, что потоки не работают как отдельный независимый поток, потому что поток должен быть запущен из другого потока. Другими словами, если вы создаете настольное приложение, и даже если вы не работаете с другими потоками, ваше приложение является однопоточным. Теперь, если вы начнете работать с потоками &, уложив их в сон, вы скоро узнаете, что вы не сможете ничего сделать в приложении. Нет & нет других потоков, которые даже не будут работать, потому что они ждут, когда первая нить закончит спать. Почему это? Потому что поток - это подпионы основного потока, и это основной поток, который ждет, когда этот подтип сна начнет просыпаться. Вы не можете проектировать нить без приложения, поскольку java является одним основным поточным приложением. Любой, да какой-либо, поток, определенный в вашем приложении, всегда выполняется внутри основного потока.

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

Чтобы положить очень длинную историю в постель, приостановив определенный пользователем поток, почти точно так же, как если бы вы назвали Thread.sleep() для любого приложения, оно приостанавливает все приложение.

+2

Неправильное использование. Сон в свежей нити будет приостанавливать существующий поток только в том случае, если существующий поток ожидает чего-то (например, для того, чтобы блокировка была доступна), и свежая нить предотвратила это (например, спать, удерживая эту блокировку). Должна быть * некоторая * зависимость между двумя для одного, чтобы остановить другую, хотя есть много косвенных путей для этого. –

0

Я написал суперпростую функцию задержки для java, которая не позволяет вашему графическому интерфейсу замораживаться. Он работал каждый раз, когда я использовал его, и я думаю, это сработает и для вас.

 void Delay(Long ms){ 

     Long dietime = System.currentTimeMillis()+ms; 
     while(System.currentTimeMillis()<dietime){ 
      //do nothing 
     } 
    } 

Для например: Для того, чтобы задержать поток на 5 millisecods использовать Delay (5L)

+0

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

+0

Не знаю, я тестировал его на платформе Android, и это не сработало. Возможно, он работает на JVM –

+0

Этот код ничем не отличается от 'Thread.sleep' i.e., он остановит выполнение текущего потока. Таким образом, выполнение в потоке графического интерфейса приведет к замораживанию графического интерфейса. –

Смежные вопросы