Если не указано иное, все слушатели AWT уведомляются относительно события, диспетчеризируют поток. Безопасно удалить/добавить слушателей из любого потока во время диспетчеризации, но изменения только эффект последующее уведомление. Например, если ключевые слушатели добавляются от другого ключевого слушателя, недавно добавленный слушатель только уведомляется относительно последующих ключевых событий.
Автозавершение работы
Согласно Спецификации Виртуальной машины Java™, разделы 2.17.9 и 2.19, виртуальная машина Java (JVM) первоначально запускает с единственным потоком недемона, который обычно вызывает main метод некоторого class. Виртуальная машина завершает все свое действие и выходит, когда одна из двух вещей происходит:
Все потоки, которые не являются оконечными потоками демона.
Некоторый поток вызывает exit метод class Runtime или class System, и работа выхода разрешается менеджером безопасности.
Это подразумевает, что, если приложение не запускает никакой, распараллеливает себя, JVM выйдет как только main завершается. Дело обстоит не так, однако, для простого приложения, которое создает и выводит на экран a java.awt.Frame:
public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
}
Причина состоит в том, что AWT инкапсулирует асинхронное событие, диспетчеризируют машину, чтобы обработать события AWT, или компоненты Swing могут стрелять. Точное поведение этой машины является зависящим от реализации. В частности это может запустить потоки помощника недемона в своих внутренних целях. Фактически, они - потоки, которые предотвращают пример выше от выхода. Единственные ограничения, введенные для поведения этой машины, следующие:
EventQueue.isDispatchThread возвраты true если и только если вызывающий поток является событием, диспетчеризируют поток, запущенный машиной;
AWTEvents которые фактически ставились в очередь к детали EventQueue (отметьте что события, отправляемые на EventQueue может быть объединен), диспетчеризируются:
Последовательно.
Таким образом, не разрешается, чтобы несколько событий от этой очереди были диспетчеризированы одновременно.
В том же самом порядке, поскольку они ставятся в очередь.
Таким образом, если AWTEvent A ставится в очередь к EventQueue прежде AWTEvent B тогда событие B не будет диспетчеризировано перед событием A.
Есть по крайней мере один живой поток недемона, в то время как есть по крайней мере один визуализуемый компонент AWT или Swing в пределах приложения (см. Component.isDisplayable).
Импликации третьего ограничения следующие:
JVM выйдет, если некоторый поток вызовет exit метод class Runtime или class System независимо от присутствия визуализуемых компонентов;
Даже если приложение завершит все потоки недемона, которые оно запустило, то JVM не будет выходить, в то время как есть по крайней мере один визуализуемый компонент.
Это зависит от реализации, если и когда потоки помощника недемона завершаются, как только все компоненты делаются невизуализуемыми. Специфичные для реализации детали даются ниже.
Зависящее от реализации поведение.
До 1.4, никогда не завершались потоки помощника.
Запускаясь с 1.4, поведение изменилось в результате фиксации для 4030718. С текущей реализацией AWT завершает все свои потоки помощника, позволяющие приложение выходить чисто, когда следующие три условия являются истиной:
Нет никакого визуализуемого AWT или компонентов Swing.
В собственной очереди событий нет никаких собственных событий.
Нет никаких событий AWT в java EventQueues.
Поэтому, автономное приложение AWT, которое хочет выйти чисто без вызова System.exit должен:
Удостоверьтесь, что весь AWT или компоненты Swing делаются невизуализуемыми, когда приложение заканчивается. Это может быть сделано, вызывая Window.dispose на всем верхнем уровне Windows. См. Frame.getFrames.
Удостоверьтесь, что никакой метод слушателей события AWT, зарегистрированных приложением в любом AWT или компоненте Swing, не может столкнуться с бесконечным циклом или зависнуть неопределенно. Например, метод слушателя AWT, инициированный некоторым событием AWT, может отправить новое событие AWT того же самого типа к EventQueue. Параметр - то, что методы слушателей события AWT обычно выполняются на потоках помощника.
Отметьте, что, в то время как приложение после этих рекомендаций выйдет чисто под нормальными условиями, не гарантируется, что это выйдет чисто во всех случаях. Два примера:
Другие пакеты могут создать визуализуемые компоненты для внутренних потребностей и никогда не делать их невизуализуемыми. См. 4515058, 4671025, и 4465537.
И Microsoft Windows и X11 позволяют приложению отправлять собственные события окнам, которые принадлежат другому приложению. С этой функцией возможно записать вредоносную программу, которая непрерывно отправит события всем доступным окнам, препятствующим тому любому приложению AWT выйти чисто.
С другой стороны, если Вы требуете, чтобы JVM продолжала работать даже после того, как приложение сделало все компоненты невизуализуемыми, следует запустить поток недемона, который блокирует навсегда.
<...>
Runnable r = new Runnable() {
public void run() {
Object o = new Object();
try {
synchronized (o) {
o.wait();
}
} catch (InterruptedException ie) {
}
}
};
Thread t = new Thread(r);
t.setDaemon(false);
t.start();
<...>
Спецификация Виртуальной машины Java™ гарантирует, что JVM не выходит, пока этот поток не завершается.