سؤال

(رمز المثال أدناه مكتفي بذاته وقابل للتشغيل ، يمكنك تجربته ، ولن يعطل نظامك :)

علق توم هاوتين على السؤال هنا: لماذا يدير الناس جافا واجهة غريبة في قائمة انتظار الحدث

الذي - التي:

من غير المحتمل أن تحطم EDT. يتم القبض على استثناءات غير محددة في Dispatch 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 تلقائيًا في كل مرة يتم فيها إلقاء استثناء غير محدد أو استثناءات غير محددة "اشتعلت ، ملقاة ويستمر الخيط" مثل توم هاوتين علق؟

ما الذي يجري هنا؟

هل كانت مفيدة؟

المحلول

للإشارة ، "السلوك الخاص لـ هذه الآلية يعتمد على التنفيذ. "على سبيل المثال ، يظل معرف الخيط دون تغيير على النظام الأساسي الخاص بي. قضايا الخيوط AWT, ، هو أن "JVM لن يخرج بينما يوجد مكون واحد على الأقل قابل للشفاء."

نصائح أخرى

سؤال مهم. كنت أعتقد أنه تم القبض على الاستثناءات وأن الخيط استمر ، لكن بعد بعض الأبحاث لست متأكدًا.

لقد قمت بتوسيع برنامجك مع

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

حيث جمعت كل مؤشرات الترابط "شوهد" ، ويزداد حجم المجموعة في كل مرة أقوم فيها بالنقر فوق "استثناء رمي"-ولكن يبدو أنه يشير إلى أن خيط جديد يتم تهيئته في حالة استثناء.

أخيرًا وجدت هذا التعليق في 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);
        }
    }
}

هناك افتراضي uncaughtexceptionHandler تم تعيينه على مؤشر ترابط إرسال الحدث ، والذي يطبع الاستثناء إلى System.out ثم يستمر في الخيط.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top