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. Web开发:需收藏的JavaScript常用技巧

    原文来自:https://www.baidu.com/home/news/data/newspage?nid=4242707244478773456&n_type=0&p_from=1 ...

  2. Python 列表list

    列表list: [ ] 类似Java中的数组. 通过索引可以取到具体位置上的值. names = ["ZhangYang","WangGui","Li ...

  3. 转载:selenium webdriver定位不到元素的五种原因及解决办法

    1.动态id定位不到元素for example:        //WebElement xiexin_element = driver.findElement(By.id("_mail_c ...

  4. dirlock.go

    // +build !windows package dirlock import (     "fmt"     "os"     "syscall ...

  5. 【cogs 775】山海经 ——Segment Tree

    题目链接:      TP 题解:   我数据结构真心是弱啊= =. 线段树好厉害啊,一直不会区间最大连续和,今天刚学习了一下233. 维护前缀最大和后缀最大,越界最大(?),再维护一个区间最大,瞎搞 ...

  6. 【树状数组】Bzoj1878[SDOI2009] HH的项链

    Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此, 他的项链变 ...

  7. BZOJ_1345_[Baltic2007]序列问题Sequence_单调栈

    BZOJ_1345_[Baltic2007]序列问题Sequence_单调栈 Description 对于一个给定的序列a1,…,an,我们对它进行一个操作reduce(i),该操作将数列中的元素ai ...

  8. BZOJ_5118_Fib数列2_矩阵乘法+欧拉定理

    BZOJ_5118_Fib数列2_矩阵乘法+欧拉定理 Description Fib定义为Fib(0)=0,Fib(1)=1,对于n≥2,Fib(n)=Fib(n-1)+Fib(n-2) 现给出N,求 ...

  9. Docker的简单实用

    一.docker的常用操作 二.其实用docker search images它就是去hub仓库里面查找:https://hub.docker.com/ 对容器的操作: 搜索镜像:[root@mast ...

  10. Java开源生鲜电商平台-通知模块设计与架构(源码可下载)

    Java开源生鲜电商平台-通知模块设计与架构(源码可下载) 说明:对于一个生鲜的B2B平台而言,通知对于我们实际的运营而言来讲分为三种方式:           1. 消息推送:(采用极光推送)   ...