java多线程-Thread线程调度CyclicBarrier循环屏障

背景
上次说完了CountDownLatch,是一个计数器,这次说说CyclicBarrier,循环屏障,我先直观的说明,这也能看做 为一个计数器,属于加法计数器,而CountDownLatch,是减法计数器。

详细说明
介绍下这个CyclicBarrir,它是用来作为一个屏障,比如要同时执行100个线程,每完成2个线程,则拦截一次,去做其他的事情。则可以使用CyclicBarrir barrir = new CyclicBarrier(2,XXX)。那么就会发现,其实CountDownLatch与CyclicBarrier基本一样,其实看样子是,但还是有实质上的区别,先看如下代码

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();
}
}
}


这个是用来装水用的类,内容很简单,装水,然后执行await()方法,等待其他完成。只有其他方法都执行到了await,才会继续执行下去。 PS:这个其他方法,就是定义的CyclicBarrier中设定的一共有几个进程在跑。如果设定为5,就需要5个方法都执行到await才会继续执行下去。
 那么接下来,是调用它的方法。

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();
}
}

执行结果如下

装水ing。。。
装水ing。。。
装水ing。。。
装水ing。。。
这个装满了,等待其他装满
这个装满了,等待其他装满
都装满了
都装满了
这个装满了,等待其他装满
这个装满了,等待其他装满
Picked up _JAVA_OPTIONS: -Xms128M -Xmx1024M
都装满了
都装满了


那么会发现,进程都在都是运行,但是运行完两个后,就开始显示“都装满了”,然后再继续执行下面两个进程,原因是因为代码设定了 CyclicBarrier barrier = new CyclicBarrier(2); 注意:这里的数字要和执行的进程数相同,进程数是它的倍数,否则会死锁。
那么说到这里,这个功能已经基本说明了,是不是功能和CountDownLatch几乎一样,那我详细说明下两者区别。

CountDownLatch与CyclicBarrier的区别

CyclicBarrier和CountDownLatch 都位于Java.util.concurrent 这个包下


CountDownLatch CyclicBarrier
减计数方式        加计数方式
计算为0时释放所有等待的线程     计数达到指定值时释放所有等待线程
计数为0时,无法重置        计数达到指定值时,计数置为0重新开        始
调用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响    调用await()方法计数加1,若加1后的值     不等于构造方法的值,则线程阻塞
不可重复利用    可重复利用


   PS:  上面总结的非常完整了。可重复利用,在上面代码中已经做到了。

 内容拓展
  大家使用时,可以看到new CyclicBarrier()时,有多个构造方法,上文我使用了第一个。那么现在看看第二个。
java多线程-Thread线程调度CyclicBarrier循环屏障 - 饶为 - 饶为先生的博客
 这个构造方法的意思,就是当执行完了规定数内的线程,去执行其他的方法。但是它传入的是一个 Runnable的对象。那么直接传入对象即可。 对象中实现了该线程的run()方法,就可以运行了。或则在构造方法中,写要运行的方法也是可以的。
代码如下
先建立一个线程类

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。
然后在修改下前面的代码,new Cyclicbarrier(2)为 new Cyclicbarrier(2,test);即可,如下:

Test test = new Test();
CyclicBarrier barrier = new CyclicBarrier(2,test);

那么执行结果

装水ing。。。
装水ing。。。
装水ing。。。
装水ing。。。
这个装满了,等待其他装满
这个装满了,等待其他装满
test
都装满了
都装满了
这个装满了,等待其他装满
这个装满了,等待其他装满
test
都装满了
都装满了

这里就可以看出,当两个进程都执行完后,直接跳入另一个进程执行,执行完后,再执行原来进程下没执行完的代码。这里是有这个先后顺序的,大家注意下。
那么这个类就介绍完了,大家可以去看看相应的使用CyclicBarrier类的题目来练习下。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值