测试 Java 方法同步的好方法是什么?
我有几个实现某些接口的类。该接口有一个契约,即某些方法应该同步,有些方法不应该同步,我想通过所有实现的单元测试来验证该契约。这些方法应该使用synchronized关键字或锁定在this
上——与synchronizedCollection()包装器非常相似。这意味着我应该能够从外部观察它。
继续 Collections.synchronizedCollection() 如果我有一个线程调用 iterator(),我仍然应该能够使用另一个线程进入像 add() 这样的方法,因为 iterator() 不应该执行任何锁定。另一方面,我应该能够在外部同步集合,并看到另一个线程在 add() 上阻塞。
有没有好的方法可以在 JUnit 测试中测试方法是否同步?我想避免长时间的睡眠陈述。
I have several classes that implement some interface. The interface has a contract, that some methods should be synchronized, and some should not, and I want to verify that contract through unit tests for all the implementations. The methods should use the synchronized keyword or be locked on this
- very similar to the synchronizedCollection() wrapper. That means I should be able to observe it externally.
To continue the example of Collections.synchronizedCollection() if I have one thread calling iterator(), I should still be able to get into methods like add() with another thread because iterator() should not do any locking. On the other hand, I should be able to synchronize on the collection externally and see that another thread blocks on add().
Is there a good way to test that a method is synchronized in a JUnit test? I want to avoid long sleep statements.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您只想检查一个方法是否具有
synchronized
修饰符,除了明显的(查看源代码/Javadoc)之外,您还可以使用反射。测试方法是否保证所有并发场景中正确同步的更普遍的问题可能是一个无法判定的问题。
If you just want to check if a method has the
synchronized
modifier, aside from the obvious (looking at the source code/Javadoc), you can also use reflection.The more general question of testing if a method guarantees proper synchronization in all concurrency scenarios is likely to be an undecidable problem.
这些都是可怕的想法,但你可以这样做...
1
2
如果你知道在任何实现中总是调用参数上的方法,你可以传递一个伪装成参数并调用 HoldLock() 的模拟对象。
就像这样:
然后等待类在 Argument 上调用 Something() 。
These are all horrible ideas, but you could do this...
1
2
If you know that methods on the arguments are always invoked in any implementation, you can pass a mock object that disguises as the argument and calls holdsLock().
So like:
Then wait for the class to invoke something() on Argument.
非常感谢 Zwei steinen 写下了我使用的方法。我解决的示例代码中存在一些问题,因此我认为值得在这里发布我的发现。
下面是作为 Scala 特征的同步测试代码:
现在假设我们要测试一个简单的类:
测试如下所示:
A big thank you to Zwei steinen for writing up the approach I used. There are a few problems in the example code that I worked through, so I thought it would be worth posting my findings here.
Here is the synchronization test code as a Scala trait:
Now let's say we want to test a simple class:
The test looks this:
使用反射,获取方法的 Method 对象,并对其调用 toString() 。 “synchronized”关键字应该出现在 toString() 的输出中。
Using reflection, get the method's Method object, and invoke toString() on it. The "synchronized" keyword should appear in toString()'s output.