【问题标题】:Concurrent Testing Queue using ConcurrentSkipListMap使用 ConcurrentSkipListMap 的并发测试队列
【发布时间】:2013-01-31 05:17:38
【问题描述】:

我最近必须完成其中一项工作面试编码练习。基本上它需要实现一个消息队列类:

  • 根据传入消息中的优先级字段维护项目。
  • 消息可以是通过 message.priorityField 值范围控制的高、中、低三个优先级类别之一。
  • 具有 getSize 和 isEmpty 方法。
  • 有一个地方(消息)方法。
  • 有一个删除方法。
  • 有 getFront() 方法(返回最高优先级的消息)

我最终没有做太多细节的事情是实现一个 MessageQueue 类,该类在内部使用 ConcurrentSkipListMap(并发且有序的映射)来保存消息。

我还实现了一个基本的 JUnit 测试用例,用于测试基本的业务需求。

现在,由于它是一个消息队列,因此消息可以同时进入,当然我需要测试实现的发生方面。

我现在越来越接近问题的核心了。

我的想法是,当单个线程与实现交互时,基本的 JUnit 测试用例应该验证代码是否正常工作。

然后我实现了一个并发测试用例,它应该验证实现的发生方面。

现在问题来了: 我应该测试哪些并发方面?

我唯一能想到的就是拥有多个在队列中注入方法的生产者线程和多个删除消息的消费者线程(通过 getFront())。 这里要验证的是,队列中的任何消息最终都会出来。

但这足够了吗?在这里可以测试哪些其他并发方面?

另外值得注意的是,我已经提交了解决方案,所以无论您提出什么建议都不会影响我申请这份工作的机会。

【问题讨论】:

    标签: java testing concurrency queue


    【解决方案1】:

    测试线程安全是一件很痛苦的事情,因为您基本上是在尝试为每个最终并发执行证明您的程序的正确性。有几种方法可以解决这个问题:

    1. 用 JMM 的条款正式证明你的程序的正确性。这将要求您讨论程序中每个明确的“发生前”边缘以及如何基于这些边缘保持一致性。这对于像队列这样基本的东西是可能的,但是随着更多的功能和边缘被抛出,它变得非常复杂。我建议你在任何情况下都完成这个过程,并在编写并发代码时记录你的意图/假设。

    2. 通过使用倒计时锁存器或在程序中的特定点暂停执行线程以强制争用的其他方法,构建演示上述预期行为的测试用例。如果走得太远,这可能会使您的代码变得一团糟,但这可能是一种非常有用的技术。

    3. 通过在足够长的时间内运行代码来统计证明正确性。这就是 concurrency torture suite 背后的原理,用于验证关于 JMM 的 JVM 实现正确性。这将要求您对参与线程的合法/非法状态形成预期,并在具有足够并行线程的机器上运行您的程序足够长的时间。如果您从未遇到非法状态,则您的程序是正确的:)。如果您运行它足够长的时间而没有达到非法状态,那么您很可能是正确的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-21
      • 2017-06-27
      • 1970-01-01
      • 1970-01-01
      • 2012-10-27
      • 1970-01-01
      • 1970-01-01
      • 2019-01-16
      相关资源
      最近更新 更多