一个概念闭锁
一个闭锁就像一道大门,直到闭锁达到终点状态之前,门一直是关闭的,没有线程可以通过,在到达终点状态时,门是打开的,允许所有线程通过。
CountDownLatch是一种同步工具|是一个灵活的闭锁,允许一个或多个线程等待一个或一组事件的发生。
构造器方法中提供的数值实际上就是闭锁需要等待的线程数量,这个计数器值只能被设置一次,而CountDwonLatch没有提供任何机制去重新设置这个值,countDown()方法对计数器做减操作,表示一个事件已经发生。如果计数器值非零时,await()方法会一直阻塞直到计算器值为零、或者中断,或者超时。
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
public void countDown() {
sync.releaseShared(1);
}
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
public boolean await(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
具体使用场景
1、使一个方法A一直等待,直到它所依赖的资源B或所需要执行的方法C都已完成之后才可以执行。
2、等待方法A或资源B都已经完成后才可以执行(例如游戏中等待所有玩家确认)。
举例:A3方法等待A1、A2方法执行后再执行(假如计算A1和A2的值都非常耗时,这时需要采用并行计算)
public static void main (String[] args)
{
ExecutorService pool = Executors.newFixedThreadPool(2);
CountDownLatch countDownLatch = new CountDownLatch(2);
for (int i = 0; i < 2; i++)
{
int finalCount = i + 1;
pool.execute(new Runnable()
{
@Override public void run ()
{
try
{
Thread.sleep(new Random().nextInt(5000));
System.out.println("-----A"+ finalCount +"执行成功----");
} catch (InterruptedException e)
{
e.printStackTrace();
} finally
{
countDownLatch.countDown();
}
}
});
}
try
{
System.out.println("-----A3等待A1和A2方法执行完毕----");
countDownLatch.await();
System.out.println("-----A3执行成功----");
} catch (InterruptedException e)
{
e.printStackTrace();
}finally
{
pool.shutdown();
}
}
运行结果
-----A3等待A1和A2方法执行完毕----
-----A2执行成功----
-----A1执行成功----
-----A3执行成功----
一个闭锁就像一道大门,直到闭锁达到终点状态之前,门一直是关闭的,没有线程可以通过,在到达终点状态时,门是打开的,允许所有线程通过。
CountDownLatch是一种同步工具|是一个灵活的闭锁,允许一个或多个线程等待一个或一组事件的发生。
构造器方法中提供的数值实际上就是闭锁需要等待的线程数量,这个计数器值只能被设置一次,而CountDwonLatch没有提供任何机制去重新设置这个值,countDown()方法对计数器做减操作,表示一个事件已经发生。如果计数器值非零时,await()方法会一直阻塞直到计算器值为零、或者中断,或者超时。
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
public void countDown() {
sync.releaseShared(1);
}
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
public boolean await(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
具体使用场景
1、使一个方法A一直等待,直到它所依赖的资源B或所需要执行的方法C都已完成之后才可以执行。
2、等待方法A或资源B都已经完成后才可以执行(例如游戏中等待所有玩家确认)。
举例:A3方法等待A1、A2方法执行后再执行(假如计算A1和A2的值都非常耗时,这时需要采用并行计算)
public static void main (String[] args)
{
ExecutorService pool = Executors.newFixedThreadPool(2);
CountDownLatch countDownLatch = new CountDownLatch(2);
for (int i = 0; i < 2; i++)
{
int finalCount = i + 1;
pool.execute(new Runnable()
{
@Override public void run ()
{
try
{
Thread.sleep(new Random().nextInt(5000));
System.out.println("-----A"+ finalCount +"执行成功----");
} catch (InterruptedException e)
{
e.printStackTrace();
} finally
{
countDownLatch.countDown();
}
}
});
}
try
{
System.out.println("-----A3等待A1和A2方法执行完毕----");
countDownLatch.await();
System.out.println("-----A3执行成功----");
} catch (InterruptedException e)
{
e.printStackTrace();
}finally
{
pool.shutdown();
}
}
运行结果
-----A3等待A1和A2方法执行完毕----
-----A2执行成功----
-----A1执行成功----
-----A3执行成功----