首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Java测试并发性

问用Java测试并发性
EN

Stack Overflow用户
提问于 2013-10-02 07:24:39
回答 1查看 1.1K关注 0票数 5

根据清单12.3中实际使用的Java并发性一书,我们可以使用以下示例代码测试并发代码:

代码语言:javascript
复制
void testTakeBlocksWhenEmpty() {
 final BoundedBuffer<Integer> bb = new BoundedBuffer<Integer>(10);
 Thread taker = new Thread() {
  public void run() {
   try {
    int unused = bb.take();
    fail(); // if we get here, it’s an error
   } catch (InterruptedException success) { }
  }
 };
 try {
  taker.start();
  Thread.sleep(LOCKUP_DETECT_TIMEOUT);
  taker.interrupt();
  taker.join(LOCKUP_DETECT_TIMEOUT);
  assertFalse(taker.isAlive());
 } catch (Exception unexpected) {
  fail();
 }
}

假设执行了以下步骤:

  1. taker线程启动。
  2. bb.take()成功返回,我们在fail()方法运行之前就有一点点时间了。
  3. 它被称为interrupt()方法。
  4. 我们位于catch线程的taker块。

因此,我们现在在catch块,但实际上测试方法失败了。它失败了,我们从未被告知。

是这样的吗?如果是的话,我们怎么解决这个问题呢?

EN

回答 1

Stack Overflow用户

发布于 2013-10-02 08:43:07

take应该在空队列上阻塞。因此,预期的事件顺序是:

  • taker.start(); =>启动线程
  • Thread.sleep(LOCKUP_DETECT_TIMEOUT);等待确保线程已启动,并已调用take。常量的实际值很难估计,但是超过几百个millis的值就足够了-或者您可以使用CountDownLatch来知道接收线程何时启动。
  • 在taker线程中:bb.take(); =>应该阻塞-如果不阻塞,则调用fail(),并且测试失败
  • 在主线程:taker.interrupt(); =>中,take()方法应该与InterruptedException一起退出
  • 在主线程中:taker.join(); =>等待一段时间,以允许接收者线程完成。
  • 在主线程中:assertFalse(taker.isAlive()); =>确认接受线程已经退出,并且不再在take方法中被阻塞。

带有锁存器的版本(它假设如果线程在take调用之前被中断,take将使用InterruptedException退出-如果没有,那么您别无选择,只能在调用started.await()之前添加一些随机睡眠):

代码语言:javascript
复制
void testTakeBlocksWhenEmpty() {
 final CountDownLatch started = new CountDownLatch(1);
 final CountDownLatch ended = new CountDownLatch(1);
 final BoundedBuffer<Integer> bb = new BoundedBuffer<Integer>(10);
 Thread taker = new Thread() {
  public void run() {
   try {
    started.countDown();
    int unused = bb.take();
    fail(); // if we get here, it’s an error
   } catch (InterruptedException success) { }
   ended.countDown();
  }
 };
 try {
  taker.start();
  started.await();
  taker.interrupt();
  assertTrue(ended.await());
 } catch (Exception unexpected) {
  fail();
 }
}

您应该在测试方法或闩锁中添加一个超时(如果测试通过,时间足够长,例如5秒)。这将避免阻塞您的整个测试套件。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19131867

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档