并发包

(计数器)CountDownLatch

  ​CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。

import java.util.concurrent.CountDownLatch;
public class CountDownlatchTest {
public static void main(String[] args) {
CountDownLatch count = new CountDownLatch(2);
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "开始执行-->" + System.currentTimeMillis());
count.countDown();
System.out.println(Thread.currentThread().getName() + "结束执行-->" + System.currentTimeMillis());
}
}).start(); new Thread(new Runnable() { @Override
public void run() {
System.out.println(Thread.currentThread().getName() + "开始执行-->" + System.currentTimeMillis());
count.countDown();
System.out.println(Thread.currentThread().getName() + "结束执行-->" + System.currentTimeMillis());
}
}).start(); try {
count.await(); // 当Count减为0 时,执行后面的代码
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println("两个子线程执行完毕....");
System.out.println("主线程继续执行.....");
for (int i = 0; i < 10; i++) {
System.out.println("main,i:" + i);
}
}
}

执行结果

Thread-0开始执行-->1564281731639
Thread-0结束执行-->1564281731639
Thread-1开始执行-->1564281731639
Thread-1结束执行-->1564281731639
两个子线程执行完毕....
主线程继续执行.....
main,i:0
main,i:1
main,i:2
main,i:3
main,i:4
main,i:5
main,i:6
main,i:7
main,i:8
main,i:9

(屏障)CyclicBarrier

  CyclicBarrier初始化时规定一个数目,然后计算调用了CyclicBarrier.await()进入等待的线程数。当线程数达到了这个数目时,所有进入等待状态的线程被唤醒并继续。
  CyclicBarrier就象它名字的意思一样,可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。
  CyclicBarrier初始时还可带一个Runnable的参数, 此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierTest {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
for (int i = 0; i < 5; i++) {
Writer writer = new Writer(cyclicBarrier);
writer.start();
}
}
} class Writer extends Thread {
private CyclicBarrier cyc; public Writer(CyclicBarrier cyc) {
this.cyc = cyc;
} @Override
public void run() {
System.out.println("线程" + Thread.currentThread().getName() + ",正在写入数据");
try {
Thread.sleep(3000);
} catch (Exception e) {
// TODO: handle exception
}
System.out.println("线程" + Thread.currentThread().getName() + ",写入数据成功.....");
try {
cyc.await();
} catch (Exception e) {
}
System.out.println("所有线程执行完毕..........");
}
}

执行结果

线程Thread-0,正在写入数据
线程Thread-2,正在写入数据
线程Thread-1,正在写入数据
线程Thread-3,正在写入数据
线程Thread-4,正在写入数据
线程Thread-3,写入数据成功.....
线程Thread-1,写入数据成功.....
线程Thread-0,写入数据成功.....
线程Thread-2,写入数据成功.....
线程Thread-4,写入数据成功.....
所有线程执行完毕..........
所有线程执行完毕..........
所有线程执行完毕..........
所有线程执行完毕..........
所有线程执行完毕..........

(计数信号量)Semaphore

  Semaphore是一种基于计数的信号量。它可以设定一个阈值,基于此,多个线程竞争获取许可信号,做自己的申请后归还,超过阈值后,线程申请许可信号将会被阻塞。 
   Semaphore可以用来构建一些对象池,资源池之类的,比如数据库连接池,我们也可以创建计数为1Semaphore,将其作为一种类似互斥锁的机制,这也叫二元信号量,表示两种互斥状态。它的用法如下:

semp.availablePermits()//函数用来获取当前可用的资源数量
semp.acquire(); //申请资源
semp.release();// 释放资源
// 创建一个计数阈值为5的信号量对象
// 只能5个线程同时访问
Semaphore semp = new Semaphore(5);
try {
// 申请许可
semp.acquire();
try {
// 业务逻辑
}catch (Exception e){
} finally {
// 释放许可
semp.release();
}
}catch(InterruptedException e){ }

案例:

需求:

  一个商店只有3个抓娃娃机,但是有10个人要来抓娃娃,那怎么办?假设10的人的编号分别为1-10,并且1号先到,10号最后到。那么1-3号来的时候必然有可用抓娃娃机,可以开始抓娃娃,4号来的时候需要看看前面3人是否有人抓完了,如果有人抓完,4号就开始抓娃娃,否则等待。同样的道理,4-10号也需要等待正在抓娃娃的人抓完才能抓,并且谁先开始抓娃娃要看等待的人是否有素质,是否能遵守先来先用抓玩玩机的规则。

代码:

import java.util.Random;
import java.util.concurrent.Semaphore; public class SemaphoreTest {
public static void main(String[] args) {
Semaphore semp = new Semaphore(3);
for (int i = 0; i <= 10; i++) {
CatchDollThread thread = new CatchDollThread("thread-" + i, semp);
thread.start();
}
}
} class CatchDollThread extends Thread {
private String name;
private Semaphore cad;
public CatchDollThread(String name, Semaphore cad) {
this.name = name;
this.cad = cad;
} @Override
public void run() {
int availablePermits = cad.availablePermits();
if (availablePermits > 0) {
System.out.println(this.name + "说: 有空闲的抓娃娃机");
} else {
System.out.println(this.name + "说: 没有空闲的娃娃机了");
}
try {
// 申请资源
cad.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.name + "开始抓娃娃" + ",此时空闲的机器:" + cad.availablePermits());
try {
Thread.sleep(new Random().nextInt(1000));
} catch (Exception e) {
}
System.out.println(this.name + "抓完娃娃");
// 释放资源
cad.release(); }
}

执行结果

thread-1说: 有空闲的抓娃娃机
thread-3说: 有空闲的抓娃娃机
thread-2说: 有空闲的抓娃娃机
thread-0说: 有空闲的抓娃娃机
thread-4说: 没有空闲的娃娃机了
thread-2开始抓娃娃,此时空闲的机器:0
thread-3开始抓娃娃,此时空闲的机器:1
thread-1开始抓娃娃,此时空闲的机器:2
thread-5说: 没有空闲的娃娃机了
thread-6说: 没有空闲的娃娃机了
thread-7说: 没有空闲的娃娃机了
thread-8说: 没有空闲的娃娃机了
thread-9说: 没有空闲的娃娃机了
thread-10说: 没有空闲的娃娃机了
thread-1抓完娃娃
thread-0开始抓娃娃,此时空闲的机器:0
thread-3抓完娃娃
thread-4开始抓娃娃,此时空闲的机器:0
thread-4抓完娃娃
thread-5开始抓娃娃,此时空闲的机器:0
thread-0抓完娃娃
thread-6开始抓娃娃,此时空闲的机器:0
thread-2抓完娃娃
thread-7开始抓娃娃,此时空闲的机器:0
thread-6抓完娃娃
thread-8开始抓娃娃,此时空闲的机器:0
thread-5抓完娃娃
thread-9开始抓娃娃,此时空闲的机器:0
thread-8抓完娃娃
thread-10开始抓娃娃,此时空闲的机器:0
thread-10抓完娃娃
thread-7抓完娃娃
thread-9抓完娃娃

Java并发包下的几个API的更多相关文章

  1. Java并发包下锁学习第一篇:介绍及学习安排

    Java并发包下锁学习第一篇:介绍及学习安排 在Java并发编程中,实现锁的方式有两种,分别是:可以使用同步锁(synchronized关键字的锁),还有lock接口下的锁.从今天起,凯哥将带领大家一 ...

  2. Java并发包下锁学习第二篇Java并发基础框架-队列同步器介绍

    Java并发包下锁学习第二篇队列同步器 还记得在第一篇文章中,讲到的locks包下的类结果图吗?如下图: ​ 从图中,我们可以看到AbstractQueuedSynchronizer这个类很重要(在本 ...

  3. Java基础(下)(JVM、API)

    Java基础(下) 第三部分:Java源程序的编辑 我们知道,计算机是不能直接理解源代码中的高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能执行高级语言编写的程序. 翻译 ...

  4. java并发包下的并发工具类

    1.Exchanger 功能:用于线程间数据的交换 应用场景:1)遗传算法,目前还不是特别理解  2)校对工作,假设A,B线程做同一件任务,可以通过数据校验判断两线程是否正确的工作 例子:是一个简单的 ...

  5. 死磕 java并发包之AtomicStampedReference源码分析(ABA问题详解)

    问题 (1)什么是ABA? (2)ABA的危害? (3)ABA的解决方法? (4)AtomicStampedReference是什么? (5)AtomicStampedReference是怎么解决AB ...

  6. Java并发包——线程安全的Collection相关类

    Java并发包——线程安全的Collection相关类 摘要:本文主要学习了Java并发包下线程安全的Collection相关的类. 部分内容来自以下博客: https://www.cnblogs.c ...

  7. Java并发包——Atomic操作

    Java并发包——Atomic操作 摘要:本文主要学习了Java并发包下的atomic包中有关原子操作的一些类. 部分内容来自以下博客: https://blog.csdn.net/qq_303796 ...

  8. Java并发包——线程安全的Map相关类

    Java并发包——线程安全的Map相关类 摘要:本文主要学习了Java并发包下线程安全的Map相关的类. 部分内容来自以下博客: https://blog.csdn.net/bill_xiang_/a ...

  9. paip.web数据绑定 下拉框的api设计 选择框 uapi python .net java swing jsf总结

    paip.web数据绑定 下拉框的api设计 选择框 uapi  python .net java swing jsf总结 ====总结: 数据绑定下拉框,Uapi 1.最好的是默认绑定..Map(k ...

随机推荐

  1. 通过Powershell修改文件默认打开方式

    修改原理 详情: Windows下通过注册表修改某个类型文件的默认打开方式和文件图标 脚本详情: Github:Change_default_programs.ps1 描述: 至少在Windows10 ...

  2. Python Iterator and Generator

    Python Iterator and Generator Iterator ​ 迭代器(Iterator)和可迭代对象(Iterable)往往是绑定的.可迭代对象就是我们平时经常用的list ,st ...

  3. 如何编写一个WebPack的插件原理及实践

    _ 阅读目录 一:webpack插件的基本原理 二:理解 Compiler对象 和 Compilation 对象 三:插件中常用的API 四:编写插件实战 回到顶部 一:webpack插件的基本原理 ...

  4. [转载]windows下mongodb安装与使用整理

    windows下mongodb安装与使用整理 一.首先安装mongodb 1.下载地址:http://www.mongodb.org/downloads 2.解压缩到自己想要安装的目录,比如d:\mo ...

  5. 心里想的VS嘴上说的

    心里想的VS嘴上说的 背景:昨天开会,在招行总行那边,今天检讨下自己不会说话,真是太难了我! 一.昨日重现 现在回想起当时的场景觉得自己也真是搞笑,这都没死,太难了我.昨天下午在五楼开会,这也是我入职 ...

  6. WPF中TimeSpan的坑

    记一次在WPF中,在将格式为“DD.HH:mm:ss”字符串转换成TimeSpan时遇到的坑 如果字符串为:DD.HH:mm:ss,转换结果正确.例如: var currentValue = &quo ...

  7. Consul的反熵

    熵 熵是衡量某个体系中事物混乱程度的一个指标,是从热力学第二定律借鉴过来的. 熵增原理 孤立系统的熵永不自动减少,熵在可逆过程中不变,在不可逆过程中增加.熵增加原理是热力学第二定律的又一种表述,它更为 ...

  8. 【openmp】for循环的break问题

    问题描述:在用openmp并行化处理for循环的时候,便无法在for循环中用break语句,那么我们如何实现这样的机制呢?在stackoverflow上看到一个不错的回答总结一下. volatile ...

  9. ubuntu下部署mongodb以及设置允许远程连接

    最近因为项目原因需要在阿里云服务器上部署mongodb,网上查阅了一些资料,特此记录一下步骤 1.运行apt-get install mongodb命令安装mongodb服务(如果提示找不到该pack ...

  10. .NET中使用WebService,以及和一般处理程序、类库的区别

    首先我们来看一下如何创建Web Service 首先在解决方案中新建项,选择ASP.NETWeb应用程序 然后选择一个空的项目就可以,单击确定 项目建完之后,在项目上右键-->添加-->新 ...