在Eclipse Oxygen.1a中JUnit测试类同步代码的调试问题
同一JVM中类锁与JUnit测试的同步行为分析
先看我们的代码示例:
public class A { public void run() { synchronized(B.class) { System.out.println("A: here"); } } } public class B { public void run() { synchronized(B.class) { System.out.println("B: here"); } } }
先明确核心逻辑:这里两个类的run方法都用了synchronized(B.class),这是类级别的锁——锁的是B类的Class对象实例。所以在同一个JVM进程内,不管是A的实例还是B的实例,想要进入这个同步块,都必须获取同一把锁,理论上这些同步块应该是串行执行的,同一时间只有一个能进入。
但你用Eclipse的“Debug As->JUnit Test”运行两个测试用例时,结果取决于你怎么运行测试:
- 如果是分别单独运行每个测试类(比如右键A的测试点一次,再右键B的测试点一次):Eclipse默认会为每个测试启动一个独立的JVM进程。这时候两个进程里的B.class是各自独立的对象,锁互不干扰,两个测试里的同步块会各自执行,不会出现互相阻塞的情况,你会看到两个测试都顺利输出对应的打印内容。
- 如果是把两个测试类放到同一个测试套件里,然后运行这个套件:这时候两个测试会在同一个JVM进程内执行,类锁就会生效——当其中一个测试的代码进入同步块持有锁时,另一个测试的代码必须等待锁释放才能进入,同步块会串行执行,打印内容会按先后顺序出现。
简单来说,关键在于JUnit测试是否运行在同一个JVM进程里,这直接决定了类锁是否能跨测试生效。
内容的提问来源于stack exchange,提问作者Julian Rost
相关产品推荐
相关产品推荐

