一种测试多线程的类:CountDownLatch

以下是java api中对该类的说明。

CountDownLatch是一个帮助完成同步的类。它允许一或多个线程等待,直到其他线程里的一组操作完成为止。

一个CountDownLatch初始化时可以指定一个count。这个类的await方法可以block当前线程,直到这个count变成0为止(每调用一次countDown()方法,count减1)。这是个仅有一次的操作,因为count不能被reset。如果你需要reset count,可以考虑使用CyclicBarrier

CountDownLatch是一种功能多样的同步工具,可以用来完成多种应用。一个用count为1来初始化的CountDownLatch可以被视为一个简单的on/off开关,或者门:所有调用了await()的线程在门外等待,直到有一个的线程调用了countDown(),门被打开。一个用count为n的CountDownLatch()可以被用来使一个线程等待,直到n个thread都完成了某个操作(每个线程完成一次操作后就调用一次CountDown()),或一个线程中某个操作被执行了n次。

CountDownLatch的一个有用的特性是,它并不要求调用countDown()的线程等待count被减为0才执行。它仅仅是简单的阻止所有调用了await()的线程通过await()方法。

你可以这么理解上面这句话:只有调用了await()的线程才会被阻止,那些仅调用countDown()的线程不会受影响。只有这样这个机制才能正常工作(如果调用countDown()的线程也会被block,那可就死锁了)。

下面是我个人的理解:

因此,这个类的意义在于,运行多线程程序时(或测试多线程程序时),除了可以利用timing来控制各个线程的行为外(显而易见的,靠时间来控制的多线程程序是不稳定的,因为sleep()等方法随时可能被中断。我在多线程相关的文章中提过,不能将多线程的逻辑正确性建立在这种不稳定因素上。),可以用CountDownLatch()来较为精确的控制线程间的交互和行为。其实这个应用和写多线程代码时使用的wait()/notifyAll()方法有些类似。

举一个简单的例子:

现在我需要测试一个类,这个类在完成了一系列操作后,会输出一行log到一个文件。在写UT时,之前的做法是:

初始化这个类,调用该类的方法后,估计完成这一系列操作需要2分钟。于是让线程sleep5 分钟(为了保险),之后,去对应的文件中检查log是否存在,并以此作为UT成功的标准。

(在我看到的UT,integration test中,这种做法到处可见。程序自身的代码一般会采用更严谨的验证方法,所以一般不会这么写。)

显而易见,也许换一台机器运行UT,或某天这台机器特别的慢,UT就会失败,进而会导致build失败。

其实只需要简单的使用CountDownLatch()就可以让测试代码更加可靠,从而增加build的稳定性。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值