Java并发--CountDownLatch CyclicBarrier ReentrantLock
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的更多相关文章
- java并发初探CyclicBarrier
java并发初探CyclicBarrier CyclicBarrier的作用 CyclicBarrier,"循环屏障"的作用就是一系列的线程等待直至达到屏障的"瓶颈点&q ...
- java并发编程——通过ReentrantLock,Condition实现银行存取款
java.util.concurrent.locks包为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器.该框架允许更灵活地使用锁和条件,但以更难用的语法为代价. Lock 接口 ...
- java 并发——CountDownLatch
java 并发--CountDownLatch 简介 public class CountDownLatch { private final Sync sync; private static fin ...
- java并发--CountDownLatch、CyclicBarrier和Semaphore
在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法. 以下 ...
- Java并发编程--CyclicBarrier
概述 CyclicBarrier是一个同步工具类,它允许一组线程互相等待,直到到达某个公共屏障点.与CountDownLatch不同的是该barrier在释放等待线程后可以重用,所以称它为循环(Cyc ...
- Java并发系列[5]----ReentrantLock源码分析
在Java5.0之前,协调对共享对象的访问可以使用的机制只有synchronized和volatile.我们知道synchronized关键字实现了内置锁,而volatile关键字保证了多线程的内存可 ...
- JAVA并发,CyclicBarrier
CyclicBarrier 翻译过来叫循环栅栏.循环障碍什么的(还是有点别扭的.所以还是别翻译了,只可意会不可言传啊).它主要的方法就是一个:await().await() 方法没被调用一次,计数便会 ...
- Java并发编程基础-ReentrantLock的机制
同步锁: 我们知道,锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时访问共享资源,在Lock接口出现之前,Java应用程序只能依靠synchronized关键字来实现同步锁 ...
- java并发编程基础-ReentrantLock及LinkedBlockingQueue源码分析
ReentrantLock是一个较为常用的锁对象.在上次分析的uil开源项目中也多次被用到,下面谈谈其概念和基本使用. 概念 一个可重入的互斥锁定 Lock,它具有与使用 synchronized 相 ...
随机推荐
- Search in Rotated Sorted Array, 查找反转有序序列。利用二分查找的思想。反转序列。
问题描述:一个有序序列经过反转,得到一个新的序列,查找新序列的某个元素.12345->45123. 算法思想:利用二分查找的思想,都是把要找的目标元素限制在一个小范围的有序序列中.这个题和二分查 ...
- 不常用的gcd公式
gcd(a^m-b^m,a^n-b^n)=a^(gcd(m,n))-b^(gcd(m,n))
- cmake手册
cmake手册 部分转载自:http://www.cnblogs.com/coderfenghc/tag/cmake/ CMake2.8.3 主索引 命令名称 用法 描述 命令选项 生成器 命令 属性 ...
- Django进阶Model篇004 - ORM常用操作
一.增加 create和save方法 实例: 1.增加一条作者记录 >>> from hello.models import * >>> Author.object ...
- linux中的kill命令
一. 定义 kill命令用来删除执行中的程序或工作.kill可将指定的信息送至程序.预设的信息为SIGTERM(15),可将指定程序终止.若仍无法终止该程序,可使用SIGKILL(9)信息尝试强制删除 ...
- wget 官方jdk
每次下载jdk都是一件头疼的事,特别是在服务器上下载. 之前想的是下载到本地,然后通过ftp工具传上去.汗.. 后来想到用wget 直接下载到服务器上. 在网上找了几个例子,wget 加参数,如:wg ...
- day5-随机数相关:random模块&string模块
一.概述 随机数在程序设计中的属于比较基础的内容,主要用于验证场景(如验证码,生成账号对应的密码等),今天结合random模块和string模块来谈谈python中随机数那些事儿. 二.随机数实现相关 ...
- windows7自动登录后锁定 & 其他VBS
首先设置自动登录(原已设置登录密码),在开始菜单搜索框输 入 “netplwiz” 按 回车,打开高级用户控制面板,然后取消对“要使用本机,用户需输入用户名和密码(E)”项的勾选,系统弹出窗口要求输入 ...
- 【python】命令行解析工具getopt用法
处理命令行参数的模块 用法: opts, args = getopt.getopt( sys.args[1:], shortStr, longList) 输入: shortStr 形式如下: &q ...
- DataV纪录
DataV 是阿里云出品的拖拽式可视化工具,专精于业务数据与地理信息融合的大数据可视化.