CyclicBarrier && CountDownLatch

今天写一下这两个类的自己所得吧。

CyclicBarrier(循环屏障):

底层使用的ReetrantLock、LockSupport、AQS、CAS等技术。

使用的含义就是设置指定数量的屏障(通过构造函数赋值),通过await()方法让线程卡在屏障处,实现线程阻塞,阻挡当前线程后续的操作, 当多个线程调用await()方法的个数达到设定的屏障数时,所有的线程都会被唤醒。

线程的阻塞和唤醒使用的LockSupport的park和unpark方法,因为unpark方法可以指定线程进行唤醒。

之所以称之为循环屏障,是因为有个计数器记录调用await()方法的数量,计数器初始值为屏障数,调用一次await()方法就减1,调用次数达到预设的屏障数的时候,计数器会减到0,这个时候释放掉这批线程锁,同时将计数器重新设置为预设的屏障数。

因此,调用await()的线程数必须是预设屏障数的整数倍,才不会有线程在阻塞,否则会有线程在一直阻塞无法释放。

 

 

CountDownLatch(倒计数锁):

核心方法countDown()/await() 方法对。

底层使用的LockSupport、AQS、CAS等技术

await()方法会使用LockSupport.park()方法阻塞线程, 让线程等待

countDown()方法会使用LockSupport.uppark(thread)方法唤醒线程

CountDownLatch有两种使用场景:

1、模拟并发

设置CountDownLatch的初试状态值是1, 创建一堆的并发线程,使用await()等待线程的其他操作, 等待几秒后,主线程使用countDown()方法,唤醒所有线程,同时执行某操作。示例代码:

CountDownLatch cdl = new CountDownLatch(1);

for(int i=0;i<50;i++){

new Thread(new Runnable() {

@Override

public void run() {

try {

cdl.await();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("并发执行====="+Thread.currentThread().getName());

}

},"我的线程【"+i+"】").start();

}



try {

System.out.println("等待1秒开始并发执行");

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

cdl.countDown();

System.out.println("并发执行结束");

 

2、模拟某个线程等待其他线程完成之后进行操作

设置CountDownLatch的初试状态值是是需要执行操作的线程数,每个线程里面,执行完操作之后,调用countDown()方法, 然后在等待的线程中调用await()进行等待,所有线程调用了countDown()之后,await()方法会被唤醒。示例代码:

public static void main(String[] args) throws InterruptedException {

CountDownLatch cdl = new CountDownLatch(1000);

test2(cdl);

}



public static void test2(CountDownLatch cdl){

long t1 = System.currentTimeMillis();

Executor e = new ScheduledThreadPoolExecutor(10);

for(int i=0;i<1000;i++){

e.execute(new MyWork(cdl,i));

}

try {

cdl.await();

} catch (InterruptedException e1) {

e1.printStackTrace();

}

long t2 = System.currentTimeMillis();

System.out.println("耗时:" + (t2 - t1) + "ms============"+cdl.getCount());

}



static class MyWork implements Runnable {

private CountDownLatch cd;

private int i;



public MyWork(CountDownLatch cd, int i) {

this.cd = cd;

this.i = i;

}



@Override

public void run() {

doWork(i);

try {

Thread.sleep(200);

} catch (InterruptedException e) {

e.printStackTrace();

}

cd.countDown();

}



private void doWork(int i) {

System.out.println("这是第" + i + "个循环,线程为" + Thread.currentThread().getName()+"==="+cd.getCount());

}

}

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值