CountDownLatch

假如有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以。
比如你想要买套房子,但是呢你现在手上没有钱。你得等这个月工资发了、然后年终奖发了、然后朋友借你得钱还给你了、然后再给朋友借一部分才可以买,这种场景你就可以使用CountDownLatch。

CountDownLatch是JDK为我们提供的一个计数器,它的操作是原子操作,同一时间只能有一个线程去操作这个它。

我们先来看一下CountDownLatch的主要方法。

1
2
3
4
5
6
7
8
9
10
//构造方法,接收计数器的数量
public CountDownLatch(int count)
//持续等待计数器归零
public void await()
//最多等待unit时间单位内timeout时间
public boolean await(long timeout, TimeUnit unit)
//计数器减1
public void countDown()
//返回现在的计数器数量
public long getCount()

下面是CountDownLatch的基本使用示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class CountDownLatchDemo {
public static CountDownLatch countDownLatch = new CountDownLatch(5);
static class ThreadDemo extends Thread {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getId() + "完成任务");
countDownLatch.countDown();
}
}
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 5; i++) {
new ThreadDemo().start();
}
countDownLatch.await();
System.out.println("全部完成任务");
}
}


CyclicBarrier

相比较于CountDownLatch,CyclicBarrier可以完成前者的全部功能,但是相比前者,它的功能更加的强大。
CyclicBarrier翻译过来的中文名称叫循环栅栏,顾名思义它可以循环使用
CyclicBarrier还可以接收一个Runnable对象,当栅栏循环一次技术后会执行一次Runnable

我们来看一下CyclicBarrier的常用方法:

1
2
3
4
5
6
7
8
9
//构造方法,第一个参数为栅栏饿长度,第二个就是上方所说的Runnable对象
public CyclicBarrier(int parties, Runnable barrierAction)
public CyclicBarrier(int parties)
//获取现在的数量
public int getParties()
//持续等待栅栏归零
public int await()
//最多等待unit时间单位内timeout时间
public int await(long timeout, TimeUnit unit)

下面是CyclicBarrier的基本使用示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class CyclicBarrierDemo {
public static CyclicBarrier cyclicBarrier = new CyclicBarrier(5,new FinallyThreadDemo());
static class ThreadDemo extends Thread {
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getId() + "完成任务");
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("到达屏障点每个线程都会瞬时继续执行");
}
}
static class FinallyThreadDemo extends Thread {
@Override
public void run() {
System.out.println("所有任务已经完成之后单独执行的任务!");
}
}
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 10; i++) {
new ThreadDemo().start();
}
}
}

观察打印结果我们可以发现:
当循环栅栏的任务执行完一轮以后,如果构造时传入了Runnable对象,则先执行Runnable对象,然后在瞬间释放所有任务的锁。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
14完成任务
15完成任务
16完成任务
17完成任务
18完成任务
所有任务已经完成之后单独执行的任务!
到达屏障点每个线程都会瞬时继续执行
到达屏障点每个线程都会瞬时继续执行
到达屏障点每个线程都会瞬时继续执行
到达屏障点每个线程都会瞬时继续执行
到达屏障点每个线程都会瞬时继续执行
19完成任务
20完成任务
21完成任务
22完成任务
23完成任务
所有任务已经完成之后单独执行的任务!
到达屏障点每个线程都会瞬时继续执行
到达屏障点每个线程都会瞬时继续执行
到达屏障点每个线程都会瞬时继续执行
到达屏障点每个线程都会瞬时继续执行
到达屏障点每个线程都会瞬时继续执行


Semaphore

在 浅谈Java中的锁:Synchronized、重入锁、读写锁 一文中,我们了解了synch和读写锁,我们发现使用锁的时候一次只允许一条线程方法。那么有什么东西可以提供更强大的控制方法么?这个东西就是信号量。

信号量提供的主要方法:

1
2
3
4
5
6
7
8
9
10
11
12
//创建具有给定许可数的信号量
Semaphore(int permits):构造方法,创建
//拿走1个许可
void acquire()
//拿走多个许可
void acquire(int n)
//释放一个许可
void release()
//释放n个许可
void release(int n):
//当前可用的许可数
int availablePermits():

下面来看使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class SemaphoreThreadDemo {
public static Semaphore semaphore = new Semaphore(5); static class ThreadDemo extends Thread {
@Override
public void run() {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getId() + "号线程在"+System.currentTimeMillis()+"获取资源");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();
}
}
} public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 30; i++) {
new ThreadDemo().start();
}
} }


LockSupport

我们在 Hello,Thread 和 生产者消费者模型 两篇文章中使用过wait和notify实现了线程之间的协作,其实关于线程协作JDK还为我们提供了另外一个工具类LockSupport。

使用LockSupport实现等待通知功能时还不需要获取锁哦

先来看一下LockSupport的常用方法:

1
2
3
4
// 禁用当前线程
static void park()
// 如果参数线程的不可用,则使其可用。
static void unpark(Thread thread)

来看一下示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class LockSupportThreadDemo {
public static Thread thread;
static class WaitThreadDemo extends Thread {
@Override
public void run() {
System.out.println("WaitThread wait,time=" + System.currentTimeMillis());
thread = Thread.currentThread();
LockSupport.park();
System.out.println("WaitThread end,time=" + System.currentTimeMillis());
}
}
static class NotifyThreadDemo extends Thread {
@Override
public void run() {
System.out.println("NotifyThread notify,time=" + System.currentTimeMillis());
LockSupport.unpark(thread);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("NotifyThread end,time=" + System.currentTimeMillis());
}
}
public static void main(String[] args) {
WaitThreadDemo waitThreadDemo = new WaitThreadDemo();
NotifyThreadDemo notifyThreadDemo = new NotifyThreadDemo();
waitThreadDemo.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
notifyThreadDemo.start();
}
}

多线程工具类:CountDownLatch、CyclicBarrier、Semaphore、LockSupport的更多相关文章

  1. Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo

    Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo CountDownLatch countDownLatch这个类使一个线程等待其他线程 ...

  2. Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger

    在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...

  3. 并发包下常见的同步工具类(CountDownLatch,CyclicBarrier,Semaphore)

    在实际开发中,碰上CPU密集且执行时间非常耗时的任务,通常我们会选择将该任务进行分割,以多线程方式同时执行若干个子任务,等这些子任务都执行完后再将所得的结果进行合并.这正是著名的map-reduce思 ...

  4. java 并发工具类CountDownLatch & CyclicBarrier

    一起在java1.5被引入的并发工具类还有CountDownLatch.CyclicBarrier.Semaphore.ConcurrentHashMap和BlockingQueue,它们都存在于ja ...

  5. 同步工具类 CountDownLatch 和 CyclicBarrier

    在开发中,一些异步操作会明显加快执行速度带来更好的体验,但同时也增加了开发的复杂度,想了用好多线程,就必须从这些方面去了解 线程的 wait() notify() notifyall() 方法 线程异 ...

  6. 并发包下常见的同步工具类详解(CountDownLatch,CyclicBarrier,Semaphore)

    目录 1. 前言 2. 闭锁CountDownLatch 2.1 CountDownLatch功能简介 2.2 使用CountDownLatch 2.3 CountDownLatch原理浅析 3.循环 ...

  7. CountDownLatch/CyclicBarrier/Semaphore 使用过吗?

    CountDownLatch/CyclicBarrier/Semaphore 使用过吗?下面详细介绍用法: 一,(等待多线程完成的)CountDownLatch  背景; countDownLatch ...

  8. Java并发工具类 - CountDownLatch

    Java并发工具类 - CountDownLatch 1.简介 CountDownLatch是Java1.5之后引入的Java并发工具类,放在java.util.concurrent包下面 http: ...

  9. Java并发工具类CountDownLatch源码中的例子

    Java并发工具类CountDownLatch源码中的例子 实例一 原文描述 /** * <p><b>Sample usage:</b> Here is a pai ...

随机推荐

  1. AJAX from S3 CORS fails on preflight OPTIONS with 403

    解决办法: 将 <!-- Sample policy --> <CORSConfiguration> <CORSRule> <AllowedOrigin> ...

  2. c# xml操作(二)

    c# xml操作(二) 此博文包含图片 (-- ::)转载▼ 标签: 杂谈 分类: c# 上次,我们介绍了增加和删除xml的一些操作,这次我们将介绍如何更改和读取xml特定节点.我们依然以上次的xml ...

  3. Python List 删除元素

    1. 使用del删除指定元素 li = [1, 2, 3, 4] del li[3] print(li) # Output [1, 2, 3] 2. 使用list方法pop删除元素 li = [1, ...

  4. 根据高德API知道坐标获取详细地址信息

    /** * 根据坐标获取具体地址 * @param coor 坐标字符串 * @return */ public static String getAdd(String coor){ String u ...

  5. BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组

    BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组 Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位 ...

  6. java面试题总结

    一.http://blog.csdn.net/moneyshi/article/details/50786786 二.http://blog.csdn.net/moneyshi/article/det ...

  7. Android--app性能问题的总结(一)

     一个应用程序的性能问题体现在很多方面,app的性能问题,很大程度上决定了使用app的用户量,如果正在使用app的过程中出现app崩溃.卡顿半天加载不出数据(跟网络也有一定的关系).用户请求事件半天获 ...

  8. asp.net core 3.0 gRPC框架小试

    什么是gRPC gRPC是google开源的一个高性能.跨语言的RPC框架,基于HTTP2协议,采用ProtoBuf 定义的IDL. gRPC 的主要优点是: 现代高性能轻量级 RPC 框架. 协定优 ...

  9. 前端笔记之Vue(一)初识SPA和Vue&webpack配置和vue安装&指令

    一.单页面应用(SPA) 1.1 C/S到B/S页面架构的转变 C/S:客户端/服务器(Client/Server)架构的软件. C/S 软件的特点: ① 从window桌面双击打开 ② 更新的时候会 ...

  10. 【转】mip-semi-fixed 走走又停停

    写在前面 MIP 中悬浮元素的特殊情况 其实组件上线已经有一段时间了,最开始看到这个需求是站长提交了一个这中功能的组件过来,不过看过代码立刻就想到了 MIP 页面的特殊性:从结果页打开的 MIP 页面 ...