Занятый цикл в другом потоке задерживает обработку EDT

У меня есть Java-программа, которая выполняет жесткий цикл в отдельном (не EDT) потоке. Хотя я думаю, что пользовательский интерфейс Swing должен быть отзывчивым, это не так. Пример программы ниже показывает проблему: нажатие кнопки «Попробовать меня» должно вызвать диалог более или менее спустя полсекунды, и должна быть возможность немедленно закрыть это диалоговое окно, щелкнув любой из его ответов. Вместо этого диалоговое окно занимает намного больше времени и / или закрывается после нажатия одной из кнопок.

Проблема возникает в Linux (на двух разных машинах с разными дистрибутивами), в Windows, на Raspberry Pi (только для серверной виртуальной машины) и в Mac OS X (сообщается другим пользователем SO).Java версии 1.8.0_65 и 1.8.0_72 (пробовал оба)Процессор i7 со многими ядрами. У EDT должно быть достаточно свободной вычислительной мощности.

Кто-нибудь имеет какие-либо идеи, почему обработка EDT задерживается, хотя существует только один занятый поток?

(Обратите внимание, что, несмотря на различные предложенияThread.sleep вызов является причиной проблемы, это не так. Это может быть удалено, и проблема все еще может быть воспроизведена, хотя она проявляется немного реже и обычно демонстрирует второе поведение, описанное выше - то есть не реагирующееJOptionPane диалог, а не задержка появления диалога. Кроме того, нет причины, по которой вызов сна должен уступать другому потоку, потому чтоесть запасные ядра процессора как уже упоминалось выше; EDT может продолжать работать на другом ядре после вызоваsleep).

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);
    }
}

Обновить: Проблема возникает только с сервером ВМ (но смотрите дальнейшее обновление). Указание клиентской ВМ (-client аргумент командной строки для исполняемого файла Java), кажется, подавляет проблему (обновление 2) на одной машине а не на другой.

Обновление 3: После нажатия на кнопку я вижу 200% -ное использование процессора процессом Java, подразумевая, что 2 полностью загруженных ядра процессора. Это не имеет смысла для меня вообще.

Обновление 4: Также происходит в Windows.

Обновление 5: Использование отладчика (Eclipse) оказывается проблематичным; кажется, что отладчик не может остановить потоки. Это весьма необычно, и я подозреваю, что в виртуальной машине существуют какие-то условия livelock или гонки, поэтому я подал ошибку в Oracle (обзор ID JI-9029194).

Обновление 6: я нашелмой отчет об ошибках в базе данных ошибок OpenJDK, (Мне не сообщили, что это было принято, я должен был искать это). Дискуссия там наиболее интересна и уже проливает некоторый свет на то, что может быть причиной этой проблемы.

Ответы на вопрос(5)

Ваш ответ на вопрос