CyclicBarrier:周期性的Barrier
可以这样理解:有这样一个栅栏,只有全部的参与者到栅栏了,这个栅栏才打开,允许大家全部通过,否则阻塞。
也就是前面的参与者到栅栏了,必须等后面其余的参与者都到栅栏之后才可以继续执行。
然后开始下一轮,下一轮仍然是前面的规则,必须要全部参与者都在等待的情况下才全部通过,否则全部阻塞.
流程如下:
1 指定了N个参与者线程,
2 只有当N个线程全部调用了await()方法之后
3 全部线程才继续往下执行步骤4,否则阻塞全部线程.
4 全部线程继续执行await()方法的代码,如果后面还有其他线程调用await()方法,那么跳转到步骤2.
package com.abc.test
import org.junit.Test
import java.util.concurrent.CountDownLatch
import java.util.concurrent.CyclicBarrier
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
class CyclicBarrierTest {
/**
* 指定了10个参与者,
* 然后启动10个线程来调用await()方法。
* 从打印中可以看出前面9个线程都在等待,
* 一直到第10个线程执行await()方法之后,
* 所有线程才继续往下执行.
*/
@Test
fun testCyclicBarrier1() {
val pools = Executors.newFixedThreadPool(10)
val barrierAction = Runnable {
println("ok " + Thread.currentThread().name);
}
val barrier = CyclicBarrier(10, barrierAction);
1.rangeTo(10).forEach {
pools.execute {
println("$it is waiting");
barrier.await()
println("$it is over");
}
}
pools.shutdown()
pools.awaitTermination(100, TimeUnit.DAYS)
}
/**
* 指定了2个参与者,
* 然后启动10个线程来调用await()方法。
* 从打印中可以看出每次都是2个线程在等待,
* 注意10必须是2的倍数.
*/
@Test
fun testCyclicBarrier2() {
val pools = Executors.newFixedThreadPool(10)
val barrierAction = Runnable {
println("ok " + Thread.currentThread().name);
}
val barrier = CyclicBarrier(2, barrierAction);
1.rangeTo(10).forEach {
pools.execute {
Thread.sleep(200 * it.toLong())
println("$it is waiting");
barrier.await()
println("$it is over");
}
}
pools.shutdown()
pools.awaitTermination(100, TimeUnit.DAYS)
}
/**
* 指定了3个参与者,
* 然后启动10个线程来调用await()方法。
* 由于10不是3的倍数,
* 会导致最后一个线程一直在等待,不会退出.
*/
@Test
fun testCyclicBarrier3() {
val pools = Executors.newFixedThreadPool(10)
val barrierAction = Runnable {
println("ok " + Thread.currentThread().name);
}
val barrier = CyclicBarrier(3, barrierAction);
1.rangeTo(10).forEach {
pools.execute {
Thread.sleep(200 * it.toLong())
println("$it is waiting");
barrier.await()
println("$it is over");
}
}
pools.shutdown()
pools.awaitTermination(100, TimeUnit.DAYS)
}
}