如何检测Swing线程策略违规

时间:2010-06-30 21:30:00

标签: java debugging swing multithreading

我正在寻找一种自动方法来检测我的代码中违反Swing的单线程策略。我正在寻找一些类似AOP代码的内容,当你在swing应用程序运行时你将它放入虚拟机中并让它记录在EDT之外修改swing组件的任何地方。

我不是AOP人,但我想在每个java.swing。*类周围创建一个AOP代理,看起来像

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

 invoke(m, args);
}

有人知道这样做的项目或实用程序吗?

3 个答案:

答案 0 :(得分:8)

我没有使用过这个特定的那个,但这个CheckThreadViolationRepaintManager应该可以解决这个问题。

它确实需要添加:

RepaintManager.setCurrentManager(new CheckThreadViolationRepaintManager());

到你的代码。

答案 1 :(得分:3)

我发现了一篇描述some solutions的4年博客帖子,但是如果你找到一个可以检测到最多EDT违规行为的帖子,我会非常感兴趣。在检测所有违规行为时,RepaintManager似乎不是防弹的。

答案 2 :(得分:3)

为了后人,这里是TofuBeer发现的CheckThreadViolationRepaintManager的简化版本。

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

只需在main方法中调用它,只要在非EDT线程上更改组件,就会记录堆栈跟踪。