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. java实现定时任务的三种方法 - 转载

    java实现定时任务的三种方法 /** * 普通thread * 这是最常见的,创建一个thread,然后让它在while循环里一直运行着, * 通过sleep方法来达到定时任务的效果.这样可以快速简 ...

  2. Android -- SQLite 数据库创建,增删改查,事务处理

    1. 概述 在Android平台上,集成了一个嵌入式关系型数据库-SQLite,SQLite3支持 NULL.INTEGER.REAL(浮点数字).TEXT(字符串文本)和BLOB(二进制对象)数据类 ...

  3. Android Studio混淆打包

    1.apk混淆打包 如果要对apk进行混淆,你要先告知gradle这个app需要混淆,并告知其混淆规则. 告知gradle需要混淆的代码 在Project/app/build.gradle中把mini ...

  4. LeetCode第[1]题(Java):Two Sum (俩数和为目标数的下标)——EASY

    题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...

  5. showdoc.js代码

    //页面加载完就执行 $(function(){ //自动根据url把当前菜单激活 var page_id = GetQueryString('page_id'); //如果中没有指定page_id, ...

  6. ng2 学习笔记(三)依赖注入与服务

    前两篇文章简单介绍了ng2的一些基础用法,基本和ng1的使用风格差不多,只是写法和开发方式变化比较大. 这一篇,来总结一下ng的依赖注入与服务.官方的教程上是把他分开来讲的,个人感觉放在一起比较容易理 ...

  7. 【2018年全国多校算法寒假训练营练习比赛(第四场)-D】小明的挖矿之旅

    题目链接:https://www.nowcoder.com/acm/contest/76/D 做题时没注意到“无论出现在哪个格子”..题中也没说明一个格子只能经过一次,其实没有想象的复杂. 判断如果点 ...

  8. Ajax中的XMLHttpRequest对象详解(转)

    XMLHttpRequest对象是Ajax技术的核心.在Internet Explorer 5中,XMLHttpRequest对象以ActiveX对象引入,被称之为XMLHTTP,它是一种支持异步请求 ...

  9. jsp中的session

    浏览器和服务器的异常通话 常用方法 setAttribute(String key,Object value);//设置值 getAttribute(String key); //取值 Invalid ...

  10. 一个 token 控件

    用于以分词形式显示某个对象的多个标签,比如: 用法 将 TagsView.h/.m 文件拷贝到你的项目文件夹,在需要用到该控件的地方导入 TagsView.h 头文件. IB 中的工作 拖一个 UIV ...