CountDownLatch

CountDownLatch可以用于一个或多个线程等待其他线程完成操作.

示例代码

private static CountDownLatch c = new CountDownLatch(1);

public static void main(String[] args) {
System.out.println("main start");
try {
new Thread(new Runnable(){
@Override
public void run() {
try {
System.out.println("thread1 start");
Thread.sleep(3000);
System.out.println("thread1 end");
} catch (InterruptedException e) {
e.printStackTrace();
}
c.countDown();
}
}, "thread1").start();
c.await();
System.out.println("main end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}

代码中, 主线程启动一个thread1线程后, 调用CountDownLatch的await()方法被阻塞, 一直等到计数器减为0.

CountDownLatch的构造方法接收一个参数n作为计数器, 可以想象为一个门有n个门闩, 每次调用countDown()方法, 计数器就减1, 即打开一个门闩. 当所有门闩都打开的时候, 调用await()方法的线程被唤醒.

await(long timeout, TimeUnit unit)方法表示等待一定时间后, 当前不会再阻塞当前线程.

CyclicBarrier

CyclicBarrier可以看作是可循环使用的屏障. 它的作用是, 让一组线程达到一个屏障时被阻塞, 直到最后一个线程到达屏障时, 屏障才会放行, 所有被阻塞的线程才可以继续运行.

示例代码

private static CyclicBarrier cb = new CyclicBarrier(3);

public static void main(String[] args) {
new Thread(new Runnable(){
@Override
public void run() {
try {
System.out.println("thread1 start");
Thread.sleep(2000);
cb.await();
System.out.println("thread1 end");
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable(){
@Override
public void run() {
try {
System.out.println("thread2 start");
Thread.sleep(2000);
cb.await();
System.out.println("thread2 end");
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
try {
cb.await();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("main");
}

代码中, CyclicBarrier的构造方法的参数表示屏障拦截的线程数, 每个线程通过await()通知CyclicBarrier已到达屏障, 然后此线程被阻塞.

另外, CyclicBarrier还有一另种构造方法CyclicBarrier(int parties, Runnable barrierAction), 表示在所有线程达到屏障时, 先执行barrierAction, 方便处理更复杂的业务场景.

await(long timeout, TimeUnit unit)方法表示等待一定时间后, 当前不会再阻塞当前线程.

与CountDownLatch的不同之处在于, CyclicBarrier可以通过reset()方法重置.

Semaphore

Semaphore(信号量)是用来控制同时访问资源的线程数.

Semaphore可以用于做流量控制, 特别是公共资源有限的场景.

示例代码

private static Semaphore sema = new Semaphore(5);

public static void main(String[] args) {
for(int i=0; i<30; i++) {
new Thread(new Runnable(){
@Override
public void run() {
try {
sema.acquire();
System.out.println(Thread.currentThread().getName());
Thread.sleep(3000);
sema.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}

代码中, 创建了30个线程, 但是同时只有5个线程可以并发执行.

线程先调用acquire()方法获取许可, 运行完成后再调用release()方法释放许可.

另外, Semaphore还提供了tryAcquire()方法来试图获取许可, 获取成功则返回true.

Exchanger

Exchanger用于两个线程交换数据.

线程通过调用exchange()方法交换数据, 先调用exchange()方法的线程会一定阻塞, 等待第二个线程调用此方法; 当两个线都调用了exchange()方法时, 两个线程就可以实现交换数据了.

private static Exchanger<String> ex = new Exchanger<String>();

public static void main(String[] args) {
new Thread(new Runnable(){
@Override
public void run() {
try {
String result = ex.exchange("I am thread1...");
System.out.println("thread1: " + result);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "thread1").start();
new Thread(new Runnable(){
@Override
public void run() {
try {
String result = ex.exchange("I am thread2...");
System.out.println("thread2: " + result);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "thread2").start();
}

Java并发编程之并发工具类的更多相关文章

  1. Java并发编程:并发容器之CopyOnWriteArrayList(转载)

    Java并发编程:并发容器之CopyOnWriteArrayList(转载) 原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW ...

  2. Java并发编程:并发容器之ConcurrentHashMap(转载)

    Java并发编程:并发容器之ConcurrentHashMap(转载) 下面这部分内容转载自: http://www.haogongju.net/art/2350374 JDK5中添加了新的concu ...

  3. 线程高级应用-心得6-java5线程并发库中同步工具类(synchronizers),新知识大用途

    1.新知识普及 2. Semaphore工具类的使用案例 package com.java5.thread.newSkill; import java.util.concurrent.Executor ...

  4. Java并发编程:并发容器之ConcurrentHashMap

    转载: Java并发编程:并发容器之ConcurrentHashMap JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的 ...

  5. Java并发编程:并发容器之CopyOnWriteArrayList

    转载: Java并发编程:并发容器之CopyOnWriteArrayList Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个 ...

  6. Java并发编程:并发容器ConcurrentHashMap

    Java并发编程:并发容器之ConcurrentHashMap(转载) 下面这部分内容转载自: http://www.haogongju.net/art/2350374 JDK5中添加了新的concu ...

  7. 【转】Java并发编程:并发容器之CopyOnWriteArrayList

    Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改, ...

  8. 【转】Java并发编程:并发容器之ConcurrentHashMap

    JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的访问都串行化了,这样保证了线程的安全性,所以这种方法的代价就是严重降低了 ...

  9. Java并发编程:并发容器之ConcurrentHashMap(转)

    本文转自:http://www.cnblogs.com/dolphin0520/p/3932905.html Java并发编程:并发容器之ConcurrentHashMap(转载) 下面这部分内容转载 ...

  10. 11、Java并发编程:并发容器之CopyOnWriteArrayList

    Java并发编程:并发容器之CopyOnWriteArrayList(转载) 原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW ...

随机推荐

  1. 看到一个对CAP简单的解释

    一个分布式系统里面,节点组成的网络本来应该是连通的.然而可能因为一些故障,使得有些节点之间不连通了,整个网络就分成了几块区域.数据就散布在了这些不连通的区域中.这就叫分区.当你一个数据项只在一个节点中 ...

  2. Python内置函数(36)——reversed

    英文文档: reversed(seq) Return a reverse iterator. seq must be an object which has a __reversed__() meth ...

  3. Docker Mysql主从同步配置搭建

    Docker Mysql主从同步配置搭建 建立目录 在虚拟机中建立目录,例如路径/home/mysql/master/data,目录结构如下: Linux中 新建文件夹命令:mkdir 文件夹名 返回 ...

  4. solr云的简单搭建(了解)

    1.认识系统架构 1.1.集群概述 1.1.1.单点服务器的问题 我们之所以要学习集群,是因为单点服务器,存在一系列的问题. 我们以前学习的JavaEE项目,都是部署在一台Tomcat上,所有的请求, ...

  5. 赛码网算法: 上台阶 ( python3实现 、c实现)

    上台阶 题目描述 有一楼梯共m级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第m级,共有多少走法?注:规定从一级到一级有0种走法. 输入输入数据首先包含一个整数n(1<=n<=1 ...

  6. RxJava系列1(简介)

    RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...

  7. Linux查看文件指定某些行的内容

    查看从第5行开始的100行内容,并把结果重定向到一个新的文件 cat file | tail -n +5 | head -n 100 > newfile.txt 查看第5行到100行的内容,并把 ...

  8. 简述ConCurrentHashMap

    HashMap: 从JDK1.2起,就有了HashMap,HashMap不是线程安全的,多线程操作时需要注意. CurrentHashMap: 在JDK1.5中,引入concurrent包,从此Map ...

  9. 【推荐】CentOS修复OpenSSH用户枚举漏洞

    注:以下所有操作均在CentOS 6.8 x86_64位系统下完成. #漏洞说明# OpenSSH(OpenBSD Secure Shell)是OpenBSD计划组所维护的一套用于安全访问远程计算机的 ...

  10. c#之监控文件结构

    如果需要知道修改文件或目录的时间,可以通过FileSystemWatcher类,这个类提供了一下应用程序可以捕获的事件,应用程序可以对事件作出响应. 使用FileSystemWatcher非常简单,首 ...