jdk1.8 J.U.C并发源码阅读------CountDownLatch源码解析
Posted Itzel_yuki
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jdk1.8 J.U.C并发源码阅读------CountDownLatch源码解析相关的知识,希望对你有一定的参考价值。
一、继承关系
public class CountDownLatch
功能:让n个线程(线程之间是共享的关系)等待另外m个线程执行完任务后再开始执行。
具体流程:将n个调用countDownLatch.await()的线程添加到CLH队列中,m个线程中最后一个执行countDownLatch.countDown()方法的线程执行tryReleaseShared成功,唤醒CLH队列中的n个共享线程。
说明:不要求和锁一起使用。初始化时指定m个线程的数量。
二、成员变量
private final Sync sync;//继承自AQS
//指定需要等待的线程的个数
public CountDownLatch(int count)
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
三、内部类
(1)Sync
private static final class Sync extends AbstractQueuedSynchronizer
private static final long serialVersionUID = 4982264981922014374L;
//构造方法,设置state的个数,表示能获取的锁的个数
Sync(int count)
setState(count);
int getCount()
return getState();
//共享锁实现,尝试获取共享锁
protected int tryAcquireShared(int acquires)
//state==0则获取成功,否则失败
return (getState() == 0) ? 1 : -1;
//释放共享锁。
protected boolean tryReleaseShared(int releases)
for (;;)
int c = getState();
if (c == 0)
return false;
//释放一个共享锁,state减1
int nextc = c-1;
//CAS更新state的值
if (compareAndSetState(c, nextc))
return nextc == 0;
四、方法说明
(1)countDown:执行一次,state减1一次,最后执行countDown的线程负责唤醒CLH中等待获取锁的所有共享状态的node中的线程
public void countDown()
//调用AQS的releaseShared方法,释放成功则进行doReleaseShared()方法,负责唤醒后继线程。
sync.releaseShared(1);
//中断则抛出异常
public void await() throws InterruptedException
sync.acquireSharedInterruptibly(1);
//中断抛出异常,超时则节点状态转换为cancelled
public boolean await(long timeout, TimeUnit unit)
throws InterruptedException
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
五、使用实例
说明:两个共享线程等待另外5个线程执行任务,当5个线程都执行完成后,这两个共享线程再开始运行
public static void testCountDown()
CountDownLatch countDownLatch=new CountDownLatch(5);
Thread[] threads=new Thread[5];
new Thread(new Runnable()
@Override
public void run()
// TODO Auto-generated method stub
LockSupport.parkNanos(1000);
System.out.println("张三开始等待");
try
countDownLatch.await();
catch (InterruptedException e)
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("人到齐了,可以开会!");
).start();
new Thread(new Runnable()
@Override
public void run()
// TODO Auto-generated method stub
LockSupport.parkNanos(1000);
System.out.println("李四开始等待");
try
countDownLatch.await();
catch (InterruptedException e)
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("人到齐了,可以开会!");
).start();
for(int i=1;i<=5;i++)
threads[i-1]=new myThread("persion"+i, countDownLatch);
threads[i-1].start();
class myThread extends Thread
String name;
CountDownLatch countDownLatch;
public myThread(String name,CountDownLatch countDownLatch)
super();
this.name=name;
this.countDownLatch=countDownLatch;
@Override
public void run()
// TODO Auto-generated method stub
try
Thread.sleep(2000);
catch (InterruptedException e)
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(name+"来了!");
countDownLatch.countDown();
输出:
张三开始等待
李四开始等待
persion4来了!
persion3来了!
persion2来了!
persion1来了!
persion5来了!
人到齐了,可以开会!
人到齐了,可以开会!
以上是关于jdk1.8 J.U.C并发源码阅读------CountDownLatch源码解析的主要内容,如果未能解决你的问题,请参考以下文章
jdk1.8 J.U.C并发源码阅读------ReentrantLock源码解析
jdk1.8 J.U.C并发源码阅读------ReentrantLock源码解析
jdk1.8 J.U.C并发源码阅读------CountDownLatch源码解析
jdk1.8 J.U.C并发源码阅读------CountDownLatch源码解析