CountDownLatch

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

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

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

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  1. //构造方法,接收计数器的数量
    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. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
  1. 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. 1
    2
    3
    4
    5
    6
    7
    8
    9
  1. //构造方法,第一个参数为栅栏饿长度,第二个就是上方所说的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. 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
  1. 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. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
  1. 14完成任务
    15完成任务
    16完成任务
    17完成任务
    18完成任务
    所有任务已经完成之后单独执行的任务!
    到达屏障点每个线程都会瞬时继续执行
    到达屏障点每个线程都会瞬时继续执行
    到达屏障点每个线程都会瞬时继续执行
    到达屏障点每个线程都会瞬时继续执行
    到达屏障点每个线程都会瞬时继续执行
    19完成任务
    20完成任务
    21完成任务
    22完成任务
    23完成任务
    所有任务已经完成之后单独执行的任务!
    到达屏障点每个线程都会瞬时继续执行
    到达屏障点每个线程都会瞬时继续执行
    到达屏障点每个线程都会瞬时继续执行
    到达屏障点每个线程都会瞬时继续执行
    到达屏障点每个线程都会瞬时继续执行


Semaphore

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

信号量提供的主要方法:

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

下面来看使用示例:

  1. 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
  1. public class SemaphoreThreadDemo {
    public static Semaphore semaphore = new Semaphore(5);
  2.  
  3. 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();
    }
    }
    }
  4.  
  5. public static void main(String[] args) throws InterruptedException {
    for (int i = 0; i < 30; i++) {
    new ThreadDemo().start();
    }
    }
  6.  
  7. }


LockSupport

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

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

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

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

来看一下示例代码:

  1. 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
  1. 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. 多进程Multiprocessing模块

    多进程 Multiprocessing 模块 先看看下面的几个方法: star() 方法启动进程, join() 方法实现进程间的同步,等待所有进程退出. close() 用来阻止多余的进程涌入进程池 ...

  2. 文字分列 CSS属性

    column 这里有一系列新的CSS属性,可以帮助你很轻松的实现文字的多列布局.让我们瞧瞧: .three-column { padding: 1em; -moz-column-count: 3; - ...

  3. 如何编写高质量JavaScript代码

    书写可维护的代码(Writing Maintainable Code ) 软件bug的修复是昂贵的,并且随着时间的推移,这些bug的成本也会增加,尤其当这些bug潜伏并慢慢出现在已经发布的软件中时.当 ...

  4. ucloud中的udisk错误“Read-only file system”修复指南

    当udisk写入数据提示错误:"Read-only file system",按照下面的方法修复:  1. 停止使用对应udisk的业务 如果有未知的进程正在操作这个硬盘,可使用命 ...

  5. ZooKeeper入门搭建教程

    http://www.wxdl.cn/cloud/zookeeper-build.html 本文是ZooKeeper的快速搭建,旨在帮助大家以最快的速度完成一个ZK集群的搭建,以便开展其它工作.本方不 ...

  6. Latex数学公式中的空格表示方法

    两个quad空格 a \qquad b 两个m的宽度 quad空格 a \quad b 一个m的宽度 大空格 a\ b 1/3m宽度 中等空格 a\;b 2/7m宽度 小空格 a\,b 1/6m宽度 ...

  7. ELK 架构之 Logstash 和 Filebeat 配置使用(采集过滤)

    相关文章: ELK 架构之 Elasticsearch 和 Kibana 安装配置 ELK 架构之 Logstash 和 Filebeat 安装配置 ELK 使用步骤:Spring Boot 日志输出 ...

  8. BigInteger类及方法应用

    注:以下内容来自传智播客(itcast)老师授课 BigInteger 可以让超过Integer范围内的数据进行运算 构造方法 public BigInteger(String val) 成员方法 p ...

  9. 【转】一则使用WinDbg工具调试iis进程调查内存占用过高的案例

    最近遇到一个奇葩内存问题,跟了三四天,把Windbg玩熟了,所以打算分享下. 症状简介 我们团队的DEV开发环境只有一台4核16G的win2012r2.这台服务器上装了SqlServer.TFS(项目 ...

  10. Android 7.0 存储系统—Vold与MountService分析(三)(转 Android 9.0 分析)

    Android的存储系统(三) 回顾:前帖分析了Vold的main()函数和NetlinkManager的函数调用流程,截止到NetlinkHandler的创建和start()调用,本帖继续分析源码 ...