Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说java并发编程-CountDownLatch,希望能够帮助你!!!。
之前我们使用wait()和notify()遇到一个问题是,Notify()是加锁的,它不释放锁,wait()得线程就要等着其释放锁。那么如果比如我开启一个线程找到日志的数据,找到了,这个时候要通知其他的线程处理,那么由于日志没有读完,wait()的要等。这种情况不能做到实时。CountDownLatch 可以解决这个问题。
1、CountDownLatch可以设置一个初始计数值,任何在这个对象上调用await()方法就会阻塞,直到计数器为0。其他的任务在结束工作后,可以调用countDown()来减少一次计数值。
2、CountDownLatch 只能使用一次,计数值不能被重用。 后面我们学习的CyclicBarrier可以重复
3、CoutDown()不会阻塞,await()会进行阻塞
知道了CoutDownLatch的用法,那么就能解决上面的问题了,定义CountDownLatch的初始计数器为1,开启线程进行await(),另一个线程进行日志的查询数据,找到了countDown()一次,计数器为0,awiat()的线程被唤醒,执行后续的日志处理操作。
下面我们看CountDownLatch的例子,
输出结果:
程序分析:
1、设置了CountDownLatch 初始计数器为100,然后10个任务进行latch.await(),阻塞等待,直到countdownlatch的计数器为0
2、然后100个任务去进行TaskPorition,每次doWork()后进行latch.countDown,计数器减少1,直到countdownlatch的计数器为0,WatingTask10个任务被激活,打印"pass!" ,从输出可以验证
3、TaskPorition的run() 会有100个任务调用,也就是执行100次其run()方法,将计数器变成0,从输出中可以看到,TaskProition的每次输出。
4、从输出结果可以看出,如果countDownLatch的计数器没有到0,await()的线程是不会被唤醒的
5、ThreadLocalRandom.current().nextInt(200), 用其是同步环境避免中间状态。静态类Random.nextInt() 也是线程安全的
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。