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. nagios无法载入静态资源

    使用nginx+nagios无法载入静态资源,看了下url中增加了一个/nagios 查看是/usr/local/nagios/etc/cgi.conf中url_html_path=/nagios 将 ...

  2. Java中的逻辑运算符

    逻辑运算符主要用于进行逻辑运算.Java 中常用的逻辑运算符如下表所示: 我们可以从“投票选举”的角度理解逻辑运算符: 1. 与:要求所有人都投票同意,才能通过某议题 2. 或:只要求一个人投票同意就 ...

  3. tensorflow笔记:模型的保存与训练过程可视化

    tensorflow笔记系列: (一) tensorflow笔记:流程,概念和简单代码注释 (二) tensorflow笔记:多层CNN代码分析 (三) tensorflow笔记:多层LSTM代码分析 ...

  4. spring3: 对JDBC的支持 之 关系数据库操作对象化

    7.3.1  概述 所谓关系数据库对象化其实就是用面向对象方式表示关系数据库操作,从而可以复用. Spring JDBC框架将数据库操作封装为一个RdbmsOperation,该对象是线程安全的.可复 ...

  5. C++构造函数知识点整理(C++11标准)

    引言 构造函数是c++中的一个比较难的语法知识点.编程实践中,由于在很多情况下可以不显示定义构造函数,或者,虽然定义构造函数的方式并不十分适当,但是程序也能正常运行,故而并不是特别引起开发者的重视. ...

  6. 牛客比赛-状压dp

    链接:https://www.nowcoder.com/acm/contest/74/F来源:牛客网 德玛西亚是一个实力雄厚.奉公守法的国家,有着功勋卓著的光荣军史. 这里非常重视正义.荣耀.职责的意 ...

  7. time模块详解

    本文转自这里: 在Python中,与时间处理有关的模块就包括:time,datetime以及calendar.这篇文章,主要讲解time模块. 在开始之前,首先要说明这几点: 在Python中,通常有 ...

  8. easyui tabs页签显示在底部属性

    data-options="tabPosition:'bottom'" 如果没有该属性  页签默认显示在最上面,效果如下 当加上了该属性  ,页签会出现在底部

  9. 注册表操作的几个windows api

    (转自:http://blog.sina.com.cn/s/blog_4e66c6cd01000bcu.html)  键管理类:   RegCloseKey():关闭注册表键释放句柄.    RegC ...

  10. C#文件与文件夹操作

    (转自:http://www.csharpwin.com/csharpspace/6649r3960.shtml) C#文件操作:C#追加文件 StreamWriter sw = File.Appen ...