Java 理论与实践: 平衡测试,第 3 部分:用方面检验设计约束
2010-01-11 00:00:00 来源:WEB开发网
清单 2. 执行 “不调用 System.gc()” 规则的静态方面 public aspect StaticGcAspect {
pointcut gcCalls() : call(void java.lang.System.gc());
declare error : gcCalls() : "Don't call System.gc!";
}
检查对 Swing 单线程规则的违犯
有一个几乎无法静态地实施的规则是线程限制 —— 指定的对象只能从一个线程访问(有时是特定线程,例如 Swing 事件线程)。Swing 程序的正确性依赖于线程限制,但是对于实施这个规则,从编译器、运行时或类库都得不到任何帮助。如果违犯了这个规则,程序就会被破坏,但是因为在测试时程序可能看起来工作正常,所以问题可能一直暴露不了。
Swing 单线线程规则指定:
Swing 组件和模块只应当从事件分派线程中创建、修改和实现。
单线程规则的早期描述允许 Swing 组件和模块在屏幕上出现之前,由其他线程访问,但是这种方式带来了线程安全问题,所以规则被强化了。使用 SwingUtilities.isEventDispatchThread() 方法,Swing 提供了一个机制,询问 “当前线程是不是事件分派线程?”。所以需要在每个 Swing 的方法调用之前插入代码,检查调用是否是由合适的线程发出的,如果不是由合适线程发出的,就抛出 AssertionError,这样就能在测试中捕捉到对单线程规则的违犯,而不会让它们在生产中造成莫名其妙的故障。
清单 3 演示了一个可以检测许多单线程规则违犯的方面:它有两部分:不应当从事件线程之外调用的方法的列表,以及要插到对这些方法的调用之前的代码。建议(要插入的代码)非常简单:检查当前线程是否是事件线程,如果不是,就抛出 AssertionError。这个方面处理了对 Swing 包中的所有方法以及扩展了最重要的 Swing 类的那些类中的方法的全部调用(以便捕捉用户提供的组件和模块),但是它排除了这些类中已知为可以安全地(或者需要)从多线程调用的方法。安全方法列表并不全面;构建一个全面的列表可能要花费一些额外时间研究 Javadoc,找到所有标记为线程安全的方法。
更多精彩
赞助商链接