Java并发编程:concurrent包下辅助类的使用

整理自:博客园-海子-http://www.cnblogs.com/dolphin0520/p/3920397.html

1、CountDownLatch用法:

  count到达0之前,调用await()的线程会一直等待,count不能重用。

  1.1、构造与方法:

CountDownLatch(int count) 构造一个用给定计数初始化的 CountDownLatch

await() 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断(InterruptedException异常)。

countDown() 递减锁存器的计数,如果计数到达零,则释放所有等待的线程。 

  1.2、实例:

 1 public class Test {
2 public static void main(String[] args) {
3 final CountDownLatch latch = new CountDownLatch(2);
4
5 new Thread(){
6 public void run() {
7 try {
8 System.out.println("子线程"+Thread.currentThread().getName()+"正在执行");
9 Thread.sleep(3000);
10 System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕");
11 latch.countDown();
12 } catch (InterruptedException e) {
13 e.printStackTrace();
14 }
15 };
16 }.start();
17
18 new Thread(){
19 public void run() {
20 try {
21 System.out.println("子线程"+Thread.currentThread().getName()+"正在执行");
22 Thread.sleep(3000);
23 System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕");
24 latch.countDown();
25 } catch (InterruptedException e) {
26 e.printStackTrace();
27 }
28 };
29 }.start();
30
31 try {
32 System.out.println(Thread.currentThread().getName()+"等待2个子线程执行完毕...");
33 latch.await();
34 System.out.println("2个子线程已经执行完毕");
35 System.out.println("继续执行主线程");
36 } catch (InterruptedException e) {
37 e.printStackTrace();
38 }
39 }
40 }
子线程Thread-0正在执行
main等待2个子线程执行完毕...
子线程Thread-1正在执行
子线程Thread-0执行完毕
子线程Thread-1执行完毕
2个子线程已经执行完毕
继续执行主线程

result

2、CyclicBarrier用法:

  回环栅栏,作用同上,让一组线程等待某个状态(barrier状态)后再同时开始执行,CyclicBarrier可以被重用。

  2.1构造与方法:

CyclicBarrier(int parties) : 创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动
CyclicBarrier(int parties, Runnable barrierAction) :创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动barrierAction。
await(): 在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。(等待知道barrier上的线程数达到parties)

  2.2实例:

public class Test {
public static void main(String[] args) {
int N = 4;
CyclicBarrier barrier = new CyclicBarrier(N); for(int i=0;i<N;i++) {
new Writer(barrier).start();
} try {
Thread.sleep(25000);
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println("CyclicBarrier重用"); for(int i=0;i<N;i++) {
new Writer(barrier).start();
}
}
static class Writer extends Thread{
private CyclicBarrier cyclicBarrier;
public Writer(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
} @Override
public void run() {
System.out.println("线程"+Thread.currentThread().getName()+"正在写入数据...");
try {
Thread.sleep(5000); //以睡眠来模拟写入数据操作
System.out.println("线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕"); cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
}catch(BrokenBarrierException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"所有线程写入完毕,继续处理其他任务...");
}
}
}
线程Thread-3正在写入数据...
线程Thread-0正在写入数据...
线程Thread-2正在写入数据...
线程Thread-1正在写入数据...
线程Thread-3写入数据完毕,等待其他线程写入完毕
线程Thread-0写入数据完毕,等待其他线程写入完毕
线程Thread-1写入数据完毕,等待其他线程写入完毕
线程Thread-2写入数据完毕,等待其他线程写入完毕
Thread-3所有线程写入完毕,继续处理其他任务...
Thread-0所有线程写入完毕,继续处理其他任务...
Thread-1所有线程写入完毕,继续处理其他任务...
Thread-2所有线程写入完毕,继续处理其他任务...
CyclicBarrier重用
线程Thread-4正在写入数据...
线程Thread-6正在写入数据...
线程Thread-5正在写入数据...
线程Thread-7正在写入数据...
线程Thread-7写入数据完毕,等待其他线程写入完毕
线程Thread-6写入数据完毕,等待其他线程写入完毕
线程Thread-4写入数据完毕,等待其他线程写入完毕
线程Thread-5写入数据完毕,等待其他线程写入完毕
Thread-5所有线程写入完毕,继续处理其他任务...
Thread-7所有线程写入完毕,继续处理其他任务...
Thread-6所有线程写入完毕,继续处理其他任务...
Thread-4所有线程写入完毕,继续处理其他任务...

result

3、Semaphore用法:信号量

  semaphore可以控制同时访问的线程个数,通过 acquire() 获取一个许可,release()释放一个许可;

  3.1、构造与方法  

Semaphore(int permits)创建具有给定的许可数和非公平的公平设置的 Semaphore。
Semaphore(int permits, boolean fair) 创建具有给定的许可数和给定的公平设置的 Semaphore。 //acquire为阻塞方法,一直等待信号量,直到获取到许可;
acquire((int permits)): 从此信号量获取一个(permits个)许可,在这之前,线程被阻塞;
release((int permits)) : 释放一个(permits个)许可,将其返回给信号量。
//tryAcquir能立即返回是否能获取许可
tryAcquire(int permits),(long timeout, TimeUnit unit)):尝试或一定时间内尝试获取许可,成功返回true,失败返回false。

  3.2、使用实例:

//假若一个工厂有5台机器,但是有8个工人,一台机器同时只能被一个工人使用,只有使用完了,其他工人才能继续使用
public class Test {
public static void main(String[] args) {
int N = 8; //工人数
Semaphore semaphore = new Semaphore(5); //机器数目
for(int i=0;i<N;i++)
new Worker(i,semaphore).start();
} static class Worker extends Thread{
private int num;
private Semaphore semaphore;
public Worker(int num,Semaphore semaphore){
this.num = num;
this.semaphore = semaphore;
} @Override
public void run() {
try {
semaphore.acquire();
System.out.println("工人"+this.num+"占用一个机器在生产...");
Thread.sleep(2000);
System.out.println("工人"+this.num+"释放出机器");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
工人1占用一个机器在生产...
工人2占用一个机器在生产...
工人0占用一个机器在生产...
工人4占用一个机器在生产...
工人3占用一个机器在生产...
工人1释放出机器
工人5占用一个机器在生产...
工人0释放出机器
工人6占用一个机器在生产...
工人2释放出机器
工人3释放出机器
工人4释放出机器
工人7占用一个机器在生产...
工人5释放出机器
工人6释放出机器
工人7释放出机器

result

Java并发机制(8)--concurrent包下辅助类的使用的更多相关文章

  1. Java 并发工具箱之concurrent包

    概述 java.util.concurrent 包是专为 Java并发编程而设计的包.包下的所有类可以分为如下几大类: locks部分:显式锁(互斥锁和速写锁)相关: atomic部分:原子变量类相关 ...

  2. Java:concurrent包下面的Map接口框架图(ConcurrentMap接口、ConcurrentHashMap实现类)

    Java集合大致可分为Set.List和Map三种体系,其中Set代表无序.不可重复的集合:List代表有序.重复的集合:而Map则代表具有映射关系的集合.Java 5之后,增加了Queue体系集合, ...

  3. Java:concurrent包下面的Collection接口框架图( CopyOnWriteArraySet, CopyOnWriteArrayList,ConcurrentLinkedQueue,BlockingQueue)

    Java集合大致可分为Set.List和Map三种体系,其中Set代表无序.不可重复的集合:List代表有序.重复的集合:而Map则代表具有映射关系的集合.Java 5之后,增加了Queue体系集合, ...

  4. Java并发编程:Concurrent锁机制解析

    Java并发编程:Concurrent锁机制解析 */--> code {color: #FF0000} pre.src {background-color: #002b36; color: # ...

  5. Java 并发系列之二:java 并发机制的底层实现原理

    1. 处理器实现原子操作 2. volatile /** 补充: 主要作用:内存可见性,是变量在多个线程中可见,修饰变量,解决一写多读的问题. 轻量级的synchronized,不会造成阻塞.性能比s ...

  6. Java并发机制(9)--Callable、Future、FutureTask的使用

    Java并发编程:Callable.Future.FutureTask的使用 整理自:博客园-海子-http://www.cnblogs.com/dolphin0520/p/3949310.html ...

  7. 《Java并发编程的艺术》Java并发机制的底层实现原理(二)

    Java并发机制的底层实现原理 1.volatile volatile相当于轻量级的synchronized,在并发编程中保证数据的可见性,使用 valotile 修饰的变量,其内存模型会增加一个 L ...

  8. 【java并发编程艺术学习】(三)第二章 java并发机制的底层实现原理 学习记录(一) volatile

    章节介绍 这一章节主要学习java并发机制的底层实现原理.主要学习volatile.synchronized和原子操作的实现原理.Java中的大部分容器和框架都依赖于此. Java代码 ==经过编译= ...

  9. Java并发机制的底层实现原理之volatile应用,初学者误看!

    volatile的介绍: Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现 ...

随机推荐

  1. HBase学习记录-API

    delete.addColumns()和delete.addColumn()的区别 /** * delete.addColumns(); * delete.addColumn(); * 区别: * a ...

  2. smbms项目核心功能实现

    SMBMS 数据库: 项目如何搭建? 考虑使用不使用Maven?依赖,Jar 1.项目搭建准备工作 搭建一个maven web项目 配置Tomcat 测试项目是否能够跑起来 导入项目中会遇到的jar包 ...

  3. 企业环境下用脚本设置ubuntu防火墙

    ubuntu防火墙设置 初始状态下直接设置即可,尽量不要尝试 重装 iptables 以及ufw,很容易导致 防火墙崩掉,最后可能只能重装系统. 配置脚本 firewall.sh #/bin/bash ...

  4. 【c#新手学习 练习 案例】 阶段项目一:开发团队调度软件

    案例是模仿java https://blog.csdn.net/bjfu170203101/article/details/109322590 改用C#:开发环境   vs2022/vscode .n ...

  5. 【C#】通过一个案例 彻底了解 Volatile和 内存屏障

    案例如下的.我个人理解是不会出现出现0,0的结果,但是很明显出现了. 说明对我对 Volatile\内存屏障\乱序排序的理解是不对. 今天就通过这个案例,理清这些概念. using System; u ...

  6. Qt:QSqlDatabase

    0.说明 QSqlDatabase类处理与数据库连接相关的操作.一个QSqlDatabase实例就代表了一个连接,连接时要提供访问数据库的driver,driver继承自QSqlDriver. 通过静 ...

  7. visual studio 快捷键重置及设置

    https://blog.csdn.net/glw0223/article/details/93195009

  8. c/c++ 日常积累

    基类是抽象类,有(纯)虚函数,子类必须要把所有的都实现啊啊啊!!!!包括子类的析构,你写一个~xx类 = default;也好啊啊啊啊啊啊啊,不然报错!!!!啊啊啊啊啊 流下了悔恨的泪水!!!... ...

  9. Java序列化流的奇妙之旅

    Java序列化流有何奇妙之处呢?通过一个个案例逐一感受序列化流. !!!好戏在后头!!! 1.IO流读写文件 先从一个普通文件读写字符串开始讲起. 例子:输出字符串到文件,再从文件中读取字符串 在某一 ...

  10. JZ-042-和为 S 的两个数字

    和为 S 的两个数字 题目描述 输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 返回值描述: 对应每个测试案例,输出两 ...