Подтвердить что ты не робот

Как выявить нарушения политики потоков Swing

Я ищу автоматический способ обнаружения нарушений однопоточной политики Swing в моем коде. Я ищу что-то в соответствии с некоторыми кодами AOP, которые вы бросаете в виртуальную машину, пока работает приложение swing, и заходите в любое место, где компонент swing изменяется вне EDT.

Я не парень AOP, но я мог бы создать прокси AOP для каждого класса java.swing. *, который выглядит как

AOP_before(Method m, Object args[]) {
 if (!isEventDispatchThread(Thread.currentThread()) {
  logStack(new RuntimeException("violation!"));
 }

 invoke(m, args);
}

Кто-нибудь знает о проекте или утилите, которая делает это?

4b9b3361

Ответ 1

Я не использовал этот конкретный, но этот CheckThreadViolationRepaintManager должен сделать трюк.

У него есть требование добавления:

RepaintManager.setCurrentManager(new CheckThreadViolationRepaintManager());

для вашего кода.

Ответ 2

Я нашел 4-летнюю запись в блоге, описывающую некоторые решения, но будет очень интересно, если вы найдете тот, который обнаруживает наиболее Нарушения EDT. RepaintManager, похоже, не является пуленепробиваемым при обнаружении всех нарушений.

Ответ 3

Для потомков здесь приведена упрощенная версия CheckThreadViolationRepaintManager, найденная TofuBeer.

RepaintManager.setCurrentManager(new RepaintManager() {
   public synchronized void addInvalidComponent( JComponent component ) {
     check( component );
     super.addInvalidComponent( component );
   }
   public void addDirtyRegion( JComponent component, int x, int y, int w, int h ) {
     check( component );
     super.addDirtyRegion( component, x, y, w, h );
   }
   private void check( JComponent c ) {
     if( !SwingUtilities.isEventDispatchThread() && c.isShowing() ) {
        new Throwable("EDT required!").printStackTrace();
     }
   }
});

Просто вызовите это в своем основном методе, и вы получите стопку стеков, регистрируемых всякий раз, когда компоненты изменяются в потоках, отличных от EDT.