import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* 2017-4-7
* author:饶为
* Administrator
*/
public class WaterCyclic extends Thread{
int time;
CyclicBarrier barrier;
/**
* @param time
* @param barrier
*/
public WaterCyclic(int time, CyclicBarrier barrier) {
super();
this.time = time;
this.barrier = barrier;
}
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
public void run() {
// TODO Auto-generated method stub
System.out.println("装水ing。。。");
try {
Thread.sleep(time);
System.out.println("这个装满了,等待其他装满");
barrier.await();
System.out.println("都装满了");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
执行结果如下package Thread;
import java.util.concurrent.CyclicBarrier;
/**
* 2017-4-7
* author:饶为
* Administrator
*/
public class CyclicBarrierTest1 {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(2);
WaterCyclic water1 = new WaterCyclic(15000, barrier);
WaterCyclic water2 = new WaterCyclic(7000, barrier);
water1.start();
water2.start();
WaterCyclic water3 = new WaterCyclic(1000, barrier);//重复利用了barrier
WaterCyclic water4 = new WaterCyclic(2000, barrier);
water3.start();
water4.start();
}
}
那么会发现,进程都在都是运行,但是运行完两个后,就开始显示“都装满了”,然后再继续执行下面两个进程,原因是因为代码设定了 CyclicBarrier barrier = new CyclicBarrier(2); 注意:这里的数字要和执行的进程数相同,进程数是它的倍数,否则会死锁。装水ing。。。
装水ing。。。
装水ing。。。
装水ing。。。
这个装满了,等待其他装满
这个装满了,等待其他装满
都装满了
都装满了
这个装满了,等待其他装满
这个装满了,等待其他装满
Picked up _JAVA_OPTIONS: -Xms128M -Xmx1024M
都装满了
都装满了
CyclicBarrier和CountDownLatch 都位于Java.util.concurrent 这个包下
CountDownLatch | CyclicBarrier |
减计数方式 | 加计数方式 |
计算为0时释放所有等待的线程 | 计数达到指定值时释放所有等待线程 |
计数为0时,无法重置 | 计数达到指定值时,计数置为0重新开 始 |
调用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响 | 调用await()方法计数加1,若加1后的值 不等于构造方法的值,则线程阻塞 |
不可重复利用 | 可重复利用 |
什么都没做,就是输出一个test。package Thread;
/**
* 2017-4-7
* author:饶为
* Administrator
*/
public class Test extends Thread {
public Test(){
}
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
public void run() {
// TODO Auto-generated method stub
System.out.println("test");
}
}
那么执行结果Test test = new Test();
CyclicBarrier barrier = new CyclicBarrier(2,test);
这里就可以看出,当两个进程都执行完后,直接跳入另一个进程执行,执行完后,再执行原来进程下没执行完的代码。这里是有这个先后顺序的,大家注意下。装水ing。。。
装水ing。。。
装水ing。。。
装水ing。。。
这个装满了,等待其他装满
这个装满了,等待其他装满
test
都装满了
都装满了
这个装满了,等待其他装满
这个装满了,等待其他装满
test
都装满了
都装满了