JAVA并发之多线程基础(4)
继上篇文章JAVA并发之多线程基础(3)谈到的信号量以及读写锁之外,接下来就继续谈及JDK中并发类的操作。
CountDownLatch
倒计时器是在某一些程序需要前置处理的时候完美搭档。例如我们经常玩的手游端,在游戏开始之前,它会去调用其他的组件,例如画面环境、人物图像、武器装备等,等加载完成之后再进入到主界面中进行游戏。
countDown()
方法是每个线程完成之后减1,代表一个线程已经到达了终点线。我们可以点击进去看到里面调用的方法:
public final boolean releaseShared(int arg) {if (tryReleaseShared(arg)) {//试图将一个线程设置共享模式doReleaseShared();//共享模式下的释放操作return true;}return false;}
复制代码
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也知道
CyclicBarrier
与CountDownLatch
用法,总的来说对于一些需要做之前准备的程序来说,他们是最佳的选择。
转载于:https://juejin.im/post/5cef83196fb9a07eaf2b758f
JAVA并发之多线程基础(4)相关推荐
- JAVA并发之多线程基础(2)
除了我们经常用的synchronized关键字(结合Object的wait()和notify()使用)之外,还有对应的上篇文章讲到的方法JAVA并发之多线程基础(1)之外,我们日常中使用到最多的也就是 ...
- JAVA并发之多线程基础(5)
上面介绍了并发编程中的栅栏等JAVA并发之多线程基础(4) .通过唯一的一个终点线来帮助确定线程是多晚开始执行下一次操作. LockSupport 提供了一个比较底层的线程挂起操作.有点类似于susp ...
- JAVA并发之多线程基础(3)
上篇文章中讲到了重入锁以及对应的条件操作,详情见JAVA并发之多线程基础(2).这篇文章我们就继续谈JDK中含有的并发操作类. Semaphore 对于大部分的锁来说,线程之间的都是互斥的,排他的,只 ...
- Java并发编程-多线程基础
Java多线程基础 1.多线程概述 实现线程的两种方式 继承Thread类 实现Runnable接口 2.线程生命周期 获取线程的名字和线程对象 3.线程的休眠 sleep方法 终止线程的休眠 强行终 ...
- 【Java程序设计】多线程基础
多线程基础 文章目录 多线程基础 一.线程的概念 (1)进程 (2)线程 二.线程的创建 (1)Thread 1.Thread类 2.Thread类的子类来创建线程 3.在新线程中完成计算某个整数的阶 ...
- java厨房_Java多线程基础
目录: 进程和线程 为什么使用多线程? 多线程的创建方式 Runnable与Thread两种方式比较 start()与run()方法 线程的生命周期/状态转换 常用方法使用与解读 线程的优先级 守护线 ...
- Java并发之从基础到框架
一 线程基础 1.synchronized取得的锁都是对象锁,哪个线程执行synchronized修饰的方法,哪个线程就获得这个方法所属对象的锁.不同对象不同锁,互不影响. 另一种情况是static ...
- java并发编程:多线程基础
文章目录 并发编程三要素 并发编程内存模型 多线程 创建线程的三种方式 volatile synchronized 线程池 ThreadPoolExcutor![在这里插入图片描述](https:// ...
- 【Java高级】多线程基础
文章目录 1.jvm启动时的线程 2. 实现线程 2.1实现线程的第一种方式 2.2 实现线程第二种方法 3.线程生命周期 4.线程名字 5.线程的sleep 6.终止线程的睡眠 7.合理终止一个线程 ...
最新文章
- git-【五】远程仓库
- 《Windows Forms编程》,真正的好书!
- swagger python自动化用例_如何让Swaggergenerated Python客户机正常工作?
- 视频播放器的极致体验优化
- B2B行业网站电话销售应具备的精神
- PHP在线考试系统实例源码
- 使用pickle模块序列化数据,优化代码
- ef 批量保存 oracle,mybatis-oracle与mysql批量添加
- 初识 Proxysql
- shell linux中shell脚本编写俄罗斯方块
- 微信小程序自定义弹窗组件
- 概率论:假设检验、极大似然估计、无偏估计
- onPageScroll微信小程序底部悬浮框滑到底部隐藏,其他情况显示
- Halcon 《机器视觉算法及应用》十例(其四)
- 将知网格式的.caj文件转换为.pdf文件
- FlinkSQL建表语句与插入语句
- Python代码加密方案总结(巨全面和详细)
- 马斯克群发卫星造天文奇观,未来三天全国多地可见
- SpringBoot集成EasyExcel的使用
- mui在线加载html,MUI 预加载页面