EDT перезапускает или не, когда исключение выдается?

(пример кода ниже является автономным и выполнимым, можно попробовать его, он не разрушит систему :)

Tom Hawtin прокомментировал вопрос здесь: Почему люди выполняют Java GUI на Очереди событий

это:

Маловероятно, что EDT отказал бы. Исключения непроверенные добавленная отправка EDT поймана, выведена и поток, продолжаются.

Может кто-то объяснять меня, что продолжается здесь (каждый раз, когда Вы нажимаете на "бросок исключение непроверенное" кнопка, деление нулем выполняется, нарочно):

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class CrashEDT extends JFrame {

    public static void main(String[] args) {
        final CrashEDT frame = new CrashEDT();
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing( WindowEvent e) {
                System.exit(0);
            }
        });
        final JButton jb = new JButton( "throw an unchecked exception" );
        jb.addActionListener( new ActionListener() {
            public void actionPerformed( ActionEvent e ) {
                System.out.println( "Thread ID:" + Thread.currentThread().getId() );
                System.out.println( 0 / Math.abs(0) );
            }
        } );
        frame.add( jb );
        frame.setSize(300, 150);
        frame.setVisible(true);
    }

}

Я получаю следующее сообщение (который является тем, что я ожидал бы):

Exception in thread "AWT-EventQueue-0" java.lang.ArithmeticException: / by zero

и мне это - право исключения непроверенное?

Вы видите, что идентификатор потока становится увеличенным каждый раз, когда Вы инициировали катастрофический отказ.

Таким образом, EDT автоматически перезапущен каждый раз, когда исключение непроверенное выдается или является неконтролируемыми исключениями, "пойманными, выведенными, и поток продолжается" как Tom Hawtin, прокомментировал?

Что продолжается здесь?

11
задан Community 23 May 2017 в 12:01
поделиться

2 ответа

Для справки: «Конкретное поведение этого механизма зависит от реализации». Например, на моей платформе идентификатор потока остается неизменным. Общий эффект, обсуждаемый в AWT Threading Issues , заключается в том, что «JVM не выйдет, пока есть хотя бы один отображаемый компонент».

4
ответ дан 3 December 2019 в 10:25
поделиться

Интересный вопрос. Я бы подумал, что исключения были пойманы и поток продолжился, но после некоторого исследования я не так уверен.

Я расширил вашу программу с помощью

Set<Thread> seenAwtThreads = new HashSet<Thread>();

, в котором я собрал все «увиденные» потоки awt, и размер набора увеличивается каждый раз, когда я нажимаю кнопку «исключить исключение», которая, кажется, предполагает, что новый поток инициализируется в случае исключения.

Наконец, я нашел этот комментарий в реализации run EventDispatchThread :

/*
 * Event dispatch thread dies in case of an uncaught exception. 
 * A new event dispatch thread for this queue will be started
 * only if a new event is posted to it. In case if no more
 * events are posted after this thread died all events that 
 * currently are in the queue will never be dispatched.
 */

Реализация метода полного запуска выглядит так:

public void run() {
    try {
        pumpEvents(new Conditional() {
            public boolean evaluate() {
                return true;
            }
        });     
    } finally {
        /*
         * This synchronized block is to secure that the event dispatch 
         * thread won't die in the middle of posting a new event to the
         * associated event queue. It is important because we notify
         * that the event dispatch thread is busy after posting a new event
         * to its queue, so the EventQueue.dispatchThread reference must
         * be valid at that point.
         */
        synchronized (theQueue) {
            if (theQueue.getDispatchThread() == this) {
                theQueue.detachDispatchThread();
            }
            /*
             * Event dispatch thread dies in case of an uncaught exception. 
             * A new event dispatch thread for this queue will be started
             * only if a new event is posted to it. In case if no more
             * events are posted after this thread died all events that 
             * currently are in the queue will never be dispatched.
             */
            /*
             * Fix for 4648733. Check both the associated java event
             * queue and the PostEventQueue.
             */
            if (theQueue.peekEvent() != null || 
                !SunToolkit.isPostEventQueueEmpty()) { 
                theQueue.initDispatchThread();
            }
            AWTAutoShutdown.getInstance().notifyThreadFree(this);
        }
    }
}
5
ответ дан 3 December 2019 в 10:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: