Busy-Schleife in anderen Threads verzögert die EDT-Verarbeitung

Ich habe ein Java-Programm, das eine enge Schleife in einem separaten (nicht-EDT-) Thread ausführt. Obwohl ich denke, dass die Swing-Benutzeroberfläche immer noch reagieren sollte, ist dies nicht der Fall. Das folgende Beispielprogramm weist das Problem auf: Wenn Sie auf die Schaltfläche "Try me" klicken, wird ungefähr eine halbe Sekunde später ein Dialogfeld geöffnet, das Sie sofort schließen können, indem Sie auf eine der Antworten klicken. Stattdessen dauert es viel länger, bis das Dialogfeld angezeigt wird, und / oder es dauert lange, bis es geschlossen wird, nachdem Sie auf eine der Schaltflächen geklickt haben.

Problem tritt unter Linux (zwei verschiedene Computer mit unterschiedlichen Distributionen), unter Windows, auf dem Raspberry Pi (nur Server-VM) und unter Mac OS X (gemeldet von einem anderen SO-Benutzer) auf.Java Version 1.8.0_65 und 1.8.0_72 (beide ausprobiert) i7 Prozessor mit vielen Kernen. Dem EDT sollte genügend freie Rechenleistung zur Verfügung stehen.

Hat jemand eine Ahnung, warum die EDT-Verarbeitung verzögert wird, obwohl es nur einen einzigen belegten Thread gibt?

(Bitte beachten Sie, dass trotz diverser Vorschläge desThread.sleep call ist die Ursache des Problems, ist es nicht. Es kann entfernt werden und das Problem kann immer noch reproduziert werden, obwohl es etwas seltener auftritt und normalerweise das oben beschriebene zweite Verhalten zeigt - d. JOptionPane dialog statt verzögerter Dialogdarstellung. Darüber hinaus gibt es keinen Grund, warum der Sleep-Aufruf an den anderen Thread übergeben werden sollte, daes gibt Ersatzprozessorkerne wie oben erwähnt; der EDT könnte nach dem Aufruf von @ auf einem anderen Core weiterlaufsleep).

import java.awt.EventQueue;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class MFrame extends JFrame
{
    public static void main(String[] args)
    {
        EventQueue.invokeLater(() -> {
            new MFrame();
        });
    }

    public MFrame()
    {
        JButton tryme = new JButton("Try me!");

        tryme.addActionListener((e) -> {
            Thread t = new Thread(() -> {
                int a = 4;
                for (int i = 0; i < 100000; i++) {
                    for (int j = 0; j < 100000; j++) {
                        a *= (i + j);
                        a += 7;
                    }
                }
                System.out.println("a = " + a);
            });

            t.start();

            // Sleep to give the other thread a chance to get going.
            // (Included because it provokes the problem more reliably,
            // but not necessary; issue still occurs without sleep call).
            try {
                Thread.sleep(500);
            }
            catch (InterruptedException ie) {
                ie.printStackTrace();
            }

            // Now display a dialog
            JOptionPane.showConfirmDialog(null, "You should see this immediately");
        });

        getContentPane().add(tryme);

        pack();
        setVisible(true);
    }
}

Aktualisieren Das Problem tritt nur bei der Server-VM auf aber siehe weiteres Update). Angeben der Client-VM -client Kommandozeilenargument für Java Executable) scheint das Problem zu unterdrücken update 2) uf einer Maschine, aber nicht auf einer ander.

Update 3: Ich sehe eine Prozessorauslastung von 200% durch den Java-Prozess, nachdem ich auf die Schaltfläche geklickt habe, was bedeutet, dass 2 Prozessorkerne vollständig geladen sind. Das ergibt für mich überhaupt keinen Sinn.

Update 4: Tritt auch unter Windows auf.

Update 5: Die Verwendung eines Debuggers (Eclipse) ist problematisch. Der Debugger scheint die Threads nicht stoppen zu können. Dies ist höchst ungewöhnlich, und ich vermute, dass die VM eine Art Livelock- oder Race-Condition aufweist. Daher habe ich einen Fehler bei Oracle gemeldet (siehe ID JI-9029194).

Update 6: Ich fandmein Fehlerbericht in der OpenJDK-Fehlerdatenbank. (Mir wurde nicht mitgeteilt, dass es angenommen wurde, ich musste danach suchen). Die Diskussion dort ist höchst interessant und wirft bereits ein Licht auf die mögliche Ursache dieses Problems.

Antworten auf die Frage(10)

Ihre Antwort auf die Frage