CountDownLatch

让一些线程堵塞直到另一个线程完成一系列操作后才被唤醒。CountDownLatch 主要有两个方法,当一个或多个线程调用 await 方法时,调用线程会被堵塞,其他线程调用 countDown 方法会将计数减一(调用 countDown 方法的线程不会堵塞),当计数其值变为零时,因调用 await 方法被堵塞的线程会被唤醒,继续执行。

假设我们有这么一个场景,教室里有班长和其他6个人在教室上自习,怎么保证班长等其他6个人都走出教室在把教室门给关掉。

public class CountDownLanchDemo {
public static void main(String[] args) {
for (int i = 0; i < 6; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " 离开了教室...");
}, String.valueOf(i)).start();
}
System.out.println("班长把门给关了,离开了教室...");
}
} 0 离开了教室...
1 离开了教室...
2 离开了教室...
3 离开了教室...
班长把门给关了,离开了教室...
5 离开了教室...
4 离开了教室...

发现班长都没有等其他人理他教室就把门给关了,此时我们就可以使用 CountDownLatch 来控制

public class CountDownLanchDemo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 0; i < 6; i++) {
new Thread(() -> {
countDownLatch.countDown();
System.out.println(Thread.currentThread().getName() + " 离开了教室...");
}, String.valueOf(i)).start();
}
countDownLatch.await();
System.out.println("班长把门给关了,离开了教室...");
}
}
0 离开了教室...
1 离开了教室...
2 离开了教室...
3 离开了教室...
4 离开了教室...
5 离开了教室...
班长把门给关了,离开了教室...
 

使用枚举完成countDownLatch案例

@Setter
@Getter
public class CountDownLatchDemo { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch=new CountDownLatch(6) ; for (int i = 1; i <=6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"国被灭.......");
countDownLatch.countDown();
},CountryEnum.getcountryEnum(i).getName()+"").start();
} countDownLatch.await(); System.out.println(CountryEnum.seven+"国一统华夏");
}
} @Getter
enum CountryEnum {
one(1, "齐", "100", "demaxiya1"),
two(2, "楚", "100", "demaxiya1"),
three(3, "燕", "100", "demaxiya1"),
four(4, "韩", "100", "demaxiya1"),
five(5, "赵", "100", "demaxiya1"),
six(6, "巍", "100", "demaxiya1"),
seven(7, "秦", "100", "demaxiya1");
private Integer id; private String name;
private String time;
private String beizhu; CountryEnum(Integer id, String name, String time, String beizhu) {
this.id = id;
this.name = name;
this.time = time;
this.beizhu = beizhu;
}
public static CountryEnum getcountryEnum(Integer id ){
for (CountryEnum value : values()) {
if (value.id==id){
return value;
}
}
return null;
}
}

打印

齐国被灭.......
燕国被灭.......
楚国被灭.......
韩国被灭.......
巍国被灭.......
赵国被灭.......
seven国一统华夏

 

、CyclicBarrier(集齐七颗龙珠召唤神龙)

  1. CycliBarrier

    可循环(Cyclic)使用的屏障。让一组线程到达一个屏障(也可叫同步点)时被阻塞,知道最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过CycliBarrier的await()方法

  2. 代码示例:

    import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier; public class CyclicBarrierDemo {
    public static void main(String[] args) {
    cyclicBarrierTest();
    } public static void cyclicBarrierTest() {
    CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
    System.out.println("====召唤神龙=====");
    });
    for (int i = 1; i <= 7; i++) {
    final int tempInt = i;
    new Thread(() -> {
    System.out.println(Thread.currentThread().getName() + "\t收集到第" + tempInt + "颗龙珠");
    try {
    cyclicBarrier.await();
    } catch (InterruptedException e) {
    e.printStackTrace();
    } catch (BrokenBarrierException e) {
    e.printStackTrace();
    }
    }, "" + i).start();
    }
    }
    }

    打印

    2 收集到第2颗龙珠
    3 收集到第3颗龙珠
    1 收集到第1颗龙珠
    5 收集到第5颗龙珠
    4 收集到第4颗龙珠
    6 收集到第6颗龙珠
    7 收集到第7颗龙珠
    ====召唤神龙=====

     

    3、Semaphore信号量

    可以代替Synchronize和Lock

    1. 信号量主要用于两个目的,一个是用于多个共享资源的互斥作用,另一个用于并发线程数的控制

    2. 代码示例:

      抢车位示例:

  3. package juc.lock.SemaphoreDemo;
    
    import java.util.concurrent.Semaphore;
    
    /**
    * @Classname SemaphoreDemo
    * @Description TODO
    * @Date 2020/7/13 23:03
    * @Created by imp
    */
    public class SemaphoreDemo { public static void main(String[] args) {
    Semaphore semaphore=new Semaphore(3); //3个车位 for (int i = 0; i < 6; i++) {
    new Thread(()->{
    try {
    //抢占车位
    semaphore.acquire();
    System.out.println(Thread.currentThread().getName()+"\t抢占到车位");
    Thread.sleep(2000);
    System.out.println(Thread.currentThread().getName()+"\t停两秒钟离开");
    } catch (InterruptedException e) {
    e.printStackTrace();
    }finally {
    semaphore.release();
    }
    },String.valueOf(i)).start();
    }
    }
    }

    打印:

    0 抢占到车位
    1 抢占到车位
    4 抢占到车位
    0 停两秒钟离开
    5 抢占到车位
    1 停两秒钟离开
    4 停两秒钟离开
    2 抢占到车位
    3 抢占到车位
    5 停两秒钟离开
    3 停两秒钟离开
    2 停两秒钟离开

     

CountDownLatch/CyclicBarrier/Semaphore 使用过吗的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. 高并发第十单:J.U.C AQS(AbstractQueuedSynchronizer) 组件:CountDownLatch. CyclicBarrier .Semaphore

    这里有一篇介绍AQS的文章 非常好: Java并发之AQS详解 AQS全名:AbstractQueuedSynchronizer,是并发容器J.U.C(java.lang.concurrent)下lo ...

  7. CountDownLatch CyclicBarrier Semaphore 比较

    document CountDownLatch A synchronization aid that allows one or more threads to wait until a set of ...

  8. 多线程中 CountDownLatch CyclicBarrier Semaphore的使用

    CountDownLatch 调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行.也可以传入时间,表示时间到之后,count还没有为0的时候,就会继续执行. package ...

  9. 等待某(N)个线程执行完再执行某个线程的几种方法(Thread.join(),CountDownLatch,CyclicBarrier,Semaphore)

    1.main线程中先调用threadA.join() ,再调用threadB.join()实现A->B->main线程的执行顺序 调用threadA.join()时,main线程会挂起,等 ...

  10. 并发工具类的使用 CountDownLatch,CyclicBarrier,Semaphore,Exchanger

    1.CountDownLatch 允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助. A CountDownLatch用给定的计数初始化. await方法阻塞,直到由于countDo ...

随机推荐

  1. PyQt(Python+Qt)学习随笔:模式窗口的windowModality属性与modal属性

    windowModality属性 windowModality属性只对窗口对象有效,保存的是哪些类型的窗口被模式窗口阻塞. 模式窗口防止其他窗口中的部件获取输入.此属性的值控制对应窗口可见时阻塞哪些类 ...

  2. 对象存储COS全球加速助力企业出海

    近年来,中国互联网行业迅猛发展,国内庞大的市场孕育出了许多现象级的产品,也锤炼出了非常成熟的产业链.与此同时,很多海外市场还处于萌芽期,存在着巨大的流量红利,越来越多的互联网企业开始加速"出 ...

  3. APIO2012 苦无 Kunai

    这题网上貌似还没有完整的题解呢,我来口胡一下~ Description \(W \times H\) 的二维坐标系,\(W, H \le 10^9\) 给 \(n (n \le 10^5)\) 个点 ...

  4. 20201207-2 openpyxl 库与模块导入

    1-1 import openpyxl # 通过文件路径,打开工作簿 wb1 = openpyxl.load_workbook('./demo_excel.xlsx') # 用 Workbook() ...

  5. oracle 修改默认临时表空间

    --查询当前数据库默认临时表空间名 select * from database_properties where property_name='DEFAULT_TEMP_TABLESPACE'; - ...

  6. Restful规则及JPA导致内存溢出

    HTTP动词 对于资源的具体操作类型,由HTTP动词表示. 常用的HTTP动词有下面五个(括号里是对应的SQL命令). GET(SELECT):从服务器取出资源(一项或多项). POST(CREATE ...

  7. 阿里不允许使用 Executors 创建线程池!那怎么使用,怎么监控?

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 五常大米好吃! 哈哈哈,是不你总买五常大米,其实五常和榆树是挨着的,榆树大米也好吃, ...

  8. C++回调函数的理解与使用

    一.回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数.回调函数不是由该函数的实现方直接调用,而是在 ...

  9. 题解 P1579 【哥德巴赫猜想(升级版)】

    蒟蒻AC代码,讲解请看题解中. 1 #include<bits/stdc++.h> 2 #include<iostream> 3 #include<cmath> / ...

  10. 点击劫持(Iframe clickJack)练习

    实验内容: 寻找一个合适的网站放入到iframe标签中.实验中测试了包括知网首页及登录界面.淘宝首页及登录界面,百度首页,微信下载界面.发现淘宝登录界面无法放入,会直接跳转到淘宝真实的登录界面,其他的 ...