InterruptedException с использованием FileSystemView без других компонентов Swing

Я расстраиваюсь, пытаясь избавиться от этого надоедливого исключения, которое отображается, когда моя программа Java завершается:

Исключение при удалении ссылки: java.lang.InterruptedException java.lang.InterruptedException в java.lang.Object.wait (собственный метод) в java.lang.ref.ReferenceQueue.remove (неизвестный источник) в java.lang.ref.ReferenceQueue. удалить (неизвестный источник) в sun.java2d.Disposer.run (неизвестный источник) в java.lang.Thread.run (неизвестный источник)

Источником моих бед является использование Класс FileSystemView. Мой код адаптирован из код на этой странице, используя File.listRoots(), а затем FileSystemView для отображения понятных имен/описаний моих дисков Windows. Упрощенная версия кода, который работает нормально, но оставляет запущенными потоки демона, вызывающие проблемы, выглядит следующим образом:

File[] roots = File.listRoots();
FileSystemView fsv = FileSystemView.getFileSystemView();
for (File f : roots) {
    System.out.format("%s (%s) %d/%d%n", fsv.getSystemDisplayName(f), fsv.getSystemTypeDescription(f),
            f.getUsableSpace(), f.getTotalSpace());
}

Использование FileSystemView, по-видимому, запускает некоторые потоки демона (Java2D Disposer, AWT-Windows, Swing-shell и т. д.), которые вызывают проблему.

Запуск этого кода сам по себе работает нормально. Запуск его в сочетании с гораздо большим количеством ресурсов Windows с использованием JNA приводит к тому, что проблема возникает гораздо чаще. Полный пример проблемного кода можно найти, выполнив тестовый класс здесь, в Windows.

Я искал ответы на все вопросы и подсказки, что можно попробовать, но, похоже, ничего не работает (пока). Для справки, я просмотрел эти две темы, среди прочего, которые описывают мои симптомы, но не дают полезных результатов:

Первая ссылка выше обсуждает потоки демона и не-демона. Я подтвердил, что «основной» поток, который достигает конца программы, когда возникает эта проблема, является единственным запущенным потоком, не являющимся демоном. Оба потока выше и многие другие источники ссылаются на удаление других компонентов Swing как на решение, но единственный код «Swing», который я использую, — это FileSystemView, и я не вижу никаких вариантов для его удаления.

Вопросы:

  • Есть ли способ красиво отключить потоки демона, которые запускаются при использовании FileSystemView?
  • Есть ли способ, которым я могу легко «обернуть» свой объект FileSystemView внутри контейнера (никогда не отображаемый пользователю), который я могу затем легко удалить (), чтобы, возможно, ответить на предыдущий вопрос?
  • Существует ли альтернатива FileSystemView, которая дает подробное описание имен дисков и томов Windows (например, A: (Floppy Drive), D: (CD-Rom) и т. д.), что позволяет избежать запуска потоков демона Swing, которые, по-видимому, вызывают эти проблемы?

person Daniel Widdis    schedule 03.09.2015    source источник
comment
Чтобы быстрее получить помощь, опубликуйте минимально воспроизводимый пример или Короткий, автономный, правильный пример.   -  person Andrew Thompson    schedule 03.09.2015
comment
Кстати, я подозреваю, что что-то, связанное с FSV, требует выполнения кода в потоке Even Dispatch. Дополнительные сведения см. в разделе Параллелизм в Swing.   -  person Andrew Thompson    schedule 03.09.2015
comment
Вы пытались обернуть код в блок try/catch?   -  person Craig    schedule 03.09.2015
comment
Эндрю, вероятно, прав, попробуйте SwingWorker при выполнении этого раздела.   -  person Craig    schedule 03.09.2015
comment
@AndrewThompson Я попытался создать минимальный пример, как вы видите в приведенном выше примере, к сожалению, (прерывистая) ошибка возникает только в гораздо большем примере. Спасибо за указание на ветку отправки событий.   -  person Daniel Widdis    schedule 03.09.2015
comment
@Craig исключение возникает, когда программа пытается завершить работу, поэтому ее невозможно отловить. Попробую SwingWorker.   -  person Daniel Widdis    schedule 03.09.2015
comment
@AndrewThompson, ваше решение идеально подходит. Я завернул FSV в свингворкер, выполнил его execute() и использовал get() для получения результатов. Пожалуйста, отправьте сообщение в разделе «Ответ», чтобы я мог принять ваш ответ.   -  person Daniel Widdis    schedule 03.09.2015
comment
@DanielWiddis рад, что смог помочь   -  person Craig    schedule 03.09.2015


Ответы (1)


Я подозреваю, что что-то, связанное с FileSystemView, требует выполнения кода в потоке Even Dispatch — потоке, используемом для диспетчеризации и обработки событий в многофункциональных клиентских настольных приложениях.

Дополнительные сведения см. в разделе Параллелизм в Swing.

person Andrew Thompson    schedule 03.09.2015
comment
Это помогло. Я использовал поток SwingWorker с FSV внутри него, выполняя и затем получая результаты, и это решает мою проблему. Спасибо! - person Daniel Widdis; 03.09.2015