CountDownLatch

CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。CountDownLatch使用一个数字count初始化,使用countDown方法使count递减,当count大于0时await方法将一直阻塞,当countDown为0时await方法将立即返回。CountDownLatch有两种典型用法,一是阻塞主线程直到所有子线程执行到某步。二是阻塞子线程直到某条件达成,下面分别是例子。

public class CountDownLatchTest {
public static void main(String[] args) throws Exception {
final CountDownLatch latch = new CountDownLatch(5);
for (int k = 0; k < 5; k++) {
final int n = k;
new Thread(new Runnable() {
private int id = n;
@Override
public void run() {
try {
System.out.println("thread " + id + " begin.");
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
}
System.out.println("thread " + id + " run over.");
latch.countDown();
}
}).start();
}
latch.await();
System.out.println("main end");
}
}

---

public class CountDownLatchTest {
public static void main(String[] args) throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
for (int k = 0; k < 5; k++) {
final int n = k;
new Thread(new Runnable() {
private int id = n;
@Override
public void run() {
try {
System.out.println("thread " + id + " begin.");
latch.await();
} catch (InterruptedException e) {
}
System.out.println("thread " + id + " run over.");
latch.countDown();
}
}).start();
}
latch.countDown();
System.out.println("main end");
}
}

---

CyclicBarrier

CyclicBarrier在初始化时规定一个数目,然后计算调用了CyclicBarrier.await()进入等待的线程数。当线程数达到了这个数目时,所有进入等待状态的线程被唤醒并继续。

CyclicBarrier初始时还可带一个Runnable的参数, 此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。通过reset函数可重置该锁。

public class CyclicBarrierTest {

    public static void main(String[] args) throws BrokenBarrierException, InterruptedException {
CyclicBarrier barrier = new CyclicBarrier(5, new Runnable() {
@Override
public void run() {
//当所有线程到达barrier时执行
System.out.println("Barrier action");
}
}); for (int k = 0; k < 4; k++) {
final int n = k;
new Thread(new Runnable() {
private int id = n;
@Override
public void run() {
try {
System.out.println("thread " + id + " begin.");
TimeUnit.SECONDS.sleep(1);
//线程在这里等待,直到所有线程都到达barrier
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("thread " + id + " run over.");
}
}).start();
} System.out.println("main end");
}
}

---

ReentrantLock

ReentrantLock是Java concurrent包中的一个互斥锁,它可以用来替代synchronized关键字,使用更加灵活。该锁同一时间只能被一个线程拥有,即执行了lock()但还未执行unlock()的线程。

/*
* ReentrantLock用来对一段代码上锁,可以代替synchronized关键字。
*/
class SomeClassWithLock { private long count1 = 0;
private long count2 = 0; //A ReentrantLock is owned by the thread last successfully locking, but not yet unlocking it.
private ReentrantLock lock = new ReentrantLock(); public void test() { //++并非原子操作,此处未上锁
count1++; lock.lock();
try {
//此处线程安全
count2++;
} finally {
//将unlock放在finally块里面
lock.unlock();
}
} public long get1() {
return count1;
}
public long get2() {
return count2;
}
} public class ReentrantLockTest { public static void main(String[] args) { final int COUNT = 10;
final CountDownLatch startSignal = new CountDownLatch(1);
final CountDownLatch doneSignal = new CountDownLatch(COUNT); final SomeClassWithLock someClass = new SomeClassWithLock(); for (int i = 0; i < COUNT; ++i) {
final int index = i;
new Thread(new Runnable() {
@Override
public void run() {
try {
startSignal.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int j = 0; j < 1000; ++j) {
someClass.test();
}
System.out.println("running thread " + index);
doneSignal.countDown();
}
}).start();
} startSignal.countDown();
try {
doneSignal.await();
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println("count1:" + someClass.get1());
System.out.println("count2:" + someClass.get2());
} }

---

执行结果:

running thread 4
running thread 7
running thread 8
running thread 2
running thread 6
running thread 0
running thread 5
running thread 9
running thread 1
running thread 3
count1:9988
count2:10000

end

Java并发--CountDownLatch CyclicBarrier ReentrantLock的更多相关文章

  1. java并发初探CyclicBarrier

    java并发初探CyclicBarrier CyclicBarrier的作用 CyclicBarrier,"循环屏障"的作用就是一系列的线程等待直至达到屏障的"瓶颈点&q ...

  2. java并发编程——通过ReentrantLock,Condition实现银行存取款

         java.util.concurrent.locks包为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器.该框架允许更灵活地使用锁和条件,但以更难用的语法为代价. Lock 接口 ...

  3. java 并发——CountDownLatch

    java 并发--CountDownLatch 简介 public class CountDownLatch { private final Sync sync; private static fin ...

  4. java并发--CountDownLatch、CyclicBarrier和Semaphore

    在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法. 以下 ...

  5. Java并发编程--CyclicBarrier

    概述 CyclicBarrier是一个同步工具类,它允许一组线程互相等待,直到到达某个公共屏障点.与CountDownLatch不同的是该barrier在释放等待线程后可以重用,所以称它为循环(Cyc ...

  6. Java并发系列[5]----ReentrantLock源码分析

    在Java5.0之前,协调对共享对象的访问可以使用的机制只有synchronized和volatile.我们知道synchronized关键字实现了内置锁,而volatile关键字保证了多线程的内存可 ...

  7. JAVA并发,CyclicBarrier

    CyclicBarrier 翻译过来叫循环栅栏.循环障碍什么的(还是有点别扭的.所以还是别翻译了,只可意会不可言传啊).它主要的方法就是一个:await().await() 方法没被调用一次,计数便会 ...

  8. Java并发编程基础-ReentrantLock的机制

    同步锁: 我们知道,锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时访问共享资源,在Lock接口出现之前,Java应用程序只能依靠synchronized关键字来实现同步锁 ...

  9. java并发编程基础-ReentrantLock及LinkedBlockingQueue源码分析

    ReentrantLock是一个较为常用的锁对象.在上次分析的uil开源项目中也多次被用到,下面谈谈其概念和基本使用. 概念 一个可重入的互斥锁定 Lock,它具有与使用 synchronized 相 ...

随机推荐

  1. Pandas索引和选择数据

    在本章中,我们将讨论如何切割和丢弃日期,并获取Pandas中大对象的子集. Python和NumPy索引运算符"[]"和属性运算符".". 可以在广泛的用例中快 ...

  2. LeetCode第[16]题(Java):3Sum Closest (和目标值最接近的三个数的和)——Medium

    题目难度:Medium 题目: Given an array S of n integers, find three integers in S such that the sum is closes ...

  3. 使用Mybatis连接数据库时报错:org.apache.ibatis.exceptions.PersistenceException: ### Error updating database.

    我的原因是字段名写错了,去数据库中复制字段名再运行就成功了.

  4. CodeForces 385 D.Bear and Floodlight 状压DP

    枚举灯的所有可能状态(亮或者不亮)(1<<20)最多可能的情况有1048576种 dp[i]表示 i 状态时灯所能照射到的最远距离(i 的二进制中如果第j位为0,则表示第j个灯不亮,否则就 ...

  5. idea结合git使用(正常项目开发过程中的使用)

    1.如何将本地项目代码提交到公司码云上面 1.项目右键 2. 在远处的remotes里面设置你的url

  6. ASP.NET MVC性能优化(实际项目中)

    前言 在开发中为了紧赶项目进度而未去关注性能的问题,在项目逐渐稳定下来后发现性能令人感到有点忧伤,于是开始去关注这方面,本篇为记录在开发中遇到的问题并解决,不喜勿喷.注意:以下问题都是在移动端上出现, ...

  7. ARM体系结构总结

    特殊功能寄存器与外设绑定,通用寄存器是与CPU绑定. ARM是RISC架构 常用ARM汇编指令只有二三十条 ARM是低功耗CPU ARM的架构非常适合单片机.嵌入式.尤其是物联网领域:而服务器等高性能 ...

  8. New Concept English three (42)

    21 33 Cave exploration, or pot-holing, as it has come to be known, is a relatively new sport. Perhap ...

  9. canvas - 圆圈内 hover效果

    链接

  10. 设备上下文-CDC绘图细节

    一,原理: 设备上下文是连接程序与设备(屏幕,打印机)的中介.其内部封装的函数可以使得绘图程序一次书写,在各种设备上都能显示.作用相当于多语言翻译家. 设备上下文内部封装了写文本,绘制椭圆,矩形,直线 ...