继上篇文章JAVA并发之多线程基础(3)谈到的信号量以及读写锁之外,接下来就继续谈及JDK中并发类的操作。

CountDownLatch

倒计时器是在某一些程序需要前置处理的时候完美搭档。例如我们经常玩的手游端,在游戏开始之前,它会去调用其他的组件,例如画面环境、人物图像、武器装备等,等加载完成之后再进入到主界面中进行游戏。

  1. countDown()方法是每个线程完成之后减1,代表一个线程已经到达了终点线。我们可以点击进去看到里面调用的方法:
public final boolean releaseShared(int arg) {if (tryReleaseShared(arg)) {//试图将一个线程设置共享模式doReleaseShared();//共享模式下的释放操作return true;}return false;}
复制代码
  1. await()是每个线程要到达的终点线,先执行完成的线程需在此等待未完成任务的线程。直至当前的countDown数量到0。
 public final void acquireSharedInterruptibly(int arg)throws InterruptedException {if (Thread.interrupted())//判断线程是否是中断throw new InterruptedException();if (tryAcquireShared(arg) < 0)//尝试在共享模式下获取doAcquireSharedInterruptibly(arg);//在共享可中断模式下获取。}
复制代码

demo:

package com.montos.lock;import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class CountDownLatchDemo implements Runnable {static final CountDownLatchDemo demo = new CountDownLatchDemo();static final CountDownLatch latch = new CountDownLatch(10);@Overridepublic void run() {try {Thread.sleep(new Random().nextInt(10) * 1000);System.out.println("checking....");latch.countDown();} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String[] args) throws InterruptedException {ExecutorService exec = Executors.newFixedThreadPool(10);for (int i = 0; i < 10; i++) {exec.submit(demo);}latch.await();System.out.println("prepare is end");exec.shutdown();}
}
复制代码

CyclicBarrier

栅栏是指每一个线程在某一处等待集合,然后接下来继续执行又到了某一处进行集合等待。可以说是上面CountDownLatch的增强版。

package com.montos.lock;import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;public class CyclicBarrierDemo {public static class Soldier implements Runnable {private String name;private final CyclicBarrier cycli;public Soldier(String name, CyclicBarrier cycli) {super();this.name = name;this.cycli = cycli;}@Overridepublic void run() {try {cycli.await();//十个线程一起等待集合doSometing();cycli.await();//十个线程一起等待事情处理完毕} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}}private void doSometing() {try {Thread.sleep(new Random().nextInt(5) * 1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(name + "任务完成");}}public static class BarrierRun implements Runnable {boolean flag;int N;public BarrierRun(boolean flag, int n) {super();this.flag = flag;N = n;}@Overridepublic void run() {if (flag) {System.out.println("士兵" + N + "任务完成");} else {System.out.println("士兵" + N + "集合完毕");flag = true;}}public static void main(String[] args) {final int N = 10;Thread[] allSoldier = new Thread[10];boolean flag = false;//N个线程到达之后,需要处理什么事情(这里是一起到达之后,处理BarrierRun事件)CyclicBarrier cycli = new CyclicBarrier(N, new BarrierRun(flag, N));System.out.println("集合队伍");for (int i = 0; i < 10; i++) {System.out.println("士兵" + i + "报道!");allSoldier[i] = new Thread(new Soldier("士" + i, cycli));allSoldier[i].start();}}}
}
复制代码

通过上面一个小的demo,可以看到CyclicBarrier的用法。其中主要的就是await()方法。寻找到里面去。主要的逻辑就是:

for (;;) {try {if (!timed)trip.await();//调用重入锁中的condition进行当前线程等待else if (nanos > 0L)nanos = trip.awaitNanos(nanos);//时间限制等待} catch (InterruptedException ie) {if (g == generation && ! g.broken) {breakBarrier();//将当前的屏障一代设置为断开并唤醒所有人throw ie;} else {Thread.currentThread().interrupt();//当前线程中断}}if (g.broken)throw new BrokenBarrierException();if (g != generation)return index;if (timed && nanos <= 0L) {breakBarrier();throw new TimeoutException();}}
复制代码

这上面就是对对应方法中的一个讲解。里面也用到了重入锁。通过上面的demo也知道CyclicBarrierCountDownLatch用法,总的来说对于一些需要做之前准备的程序来说,他们是最佳的选择。

转载于:https://juejin.im/post/5cef83196fb9a07eaf2b758f

JAVA并发之多线程基础(4)相关推荐

  1. JAVA并发之多线程基础(2)

    除了我们经常用的synchronized关键字(结合Object的wait()和notify()使用)之外,还有对应的上篇文章讲到的方法JAVA并发之多线程基础(1)之外,我们日常中使用到最多的也就是 ...

  2. JAVA并发之多线程基础(5)

    上面介绍了并发编程中的栅栏等JAVA并发之多线程基础(4) .通过唯一的一个终点线来帮助确定线程是多晚开始执行下一次操作. LockSupport 提供了一个比较底层的线程挂起操作.有点类似于susp ...

  3. JAVA并发之多线程基础(3)

    上篇文章中讲到了重入锁以及对应的条件操作,详情见JAVA并发之多线程基础(2).这篇文章我们就继续谈JDK中含有的并发操作类. Semaphore 对于大部分的锁来说,线程之间的都是互斥的,排他的,只 ...

  4. Java并发编程-多线程基础

    Java多线程基础 1.多线程概述 实现线程的两种方式 继承Thread类 实现Runnable接口 2.线程生命周期 获取线程的名字和线程对象 3.线程的休眠 sleep方法 终止线程的休眠 强行终 ...

  5. 【Java程序设计】多线程基础

    多线程基础 文章目录 多线程基础 一.线程的概念 (1)进程 (2)线程 二.线程的创建 (1)Thread 1.Thread类 2.Thread类的子类来创建线程 3.在新线程中完成计算某个整数的阶 ...

  6. java厨房_Java多线程基础

    目录: 进程和线程 为什么使用多线程? 多线程的创建方式 Runnable与Thread两种方式比较 start()与run()方法 线程的生命周期/状态转换 常用方法使用与解读 线程的优先级 守护线 ...

  7. Java并发之从基础到框架

    一  线程基础 1.synchronized取得的锁都是对象锁,哪个线程执行synchronized修饰的方法,哪个线程就获得这个方法所属对象的锁.不同对象不同锁,互不影响. 另一种情况是static ...

  8. java并发编程:多线程基础

    文章目录 并发编程三要素 并发编程内存模型 多线程 创建线程的三种方式 volatile synchronized 线程池 ThreadPoolExcutor![在这里插入图片描述](https:// ...

  9. 【Java高级】多线程基础

    文章目录 1.jvm启动时的线程 2. 实现线程 2.1实现线程的第一种方式 2.2 实现线程第二种方法 3.线程生命周期 4.线程名字 5.线程的sleep 6.终止线程的睡眠 7.合理终止一个线程 ...

最新文章

  1. git-【五】远程仓库
  2. 《Windows Forms编程》,真正的好书!
  3. swagger python自动化用例_如何让Swaggergenerated Python客户机正常工作?
  4. 视频播放器的极致体验优化
  5. B2B行业网站电话销售应具备的精神
  6. PHP在线考试系统实例源码
  7. 使用pickle模块序列化数据,优化代码
  8. ef 批量保存 oracle,mybatis-oracle与mysql批量添加
  9. 初识 Proxysql
  10. shell linux中shell脚本编写俄罗斯方块
  11. 微信小程序自定义弹窗组件
  12. 概率论:假设检验、极大似然估计、无偏估计
  13. onPageScroll微信小程序底部悬浮框滑到底部隐藏,其他情况显示
  14. Halcon 《机器视觉算法及应用》十例(其四)
  15. 将知网格式的.caj文件转换为.pdf文件
  16. FlinkSQL建表语句与插入语句
  17. Python代码加密方案总结(巨全面和详细)
  18. 马斯克群发卫星造天文奇观,未来三天全国多地可见
  19. SpringBoot集成EasyExcel的使用
  20. mui在线加载html,MUI 预加载页面

热门文章

  1. 批量生成zabbix screen xml file
  2. Wordpress 自定义文章类型添加 Categoried、Tags
  3. SAS接口互连完全指南
  4. 回复《论WEB标准专家》。
  5. nginx lua获取客户端ip
  6. VMware (CentOS 6.x)克隆导致的网卡问题
  7. python版判断IP地址
  8. php后台登陆页面代码
  9. Oracle笔记(一) Oracle简介及安装
  10. 数据通过蓝牙传输中...70.46k/s