JUC并发编程学习笔记(七)常用的辅助类
常用的辅助类
CountDownLatch
这是一个JUC计数器辅助类,计数器有加有减,这是减。

使用方法
package org.example.demo;
import java.util.concurrent.CountDownLatch;
//线程计数器
public class CountDownLatchDemo {
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(6);//总数为6,必须要执行任务时用
for (int i = 0; i < 6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+" go out");
countDownLatch.countDown();//总数减1
},String.valueOf(i)).start();
}
try {
countDownLatch.await();//等待总数变为0才会往下执行,相当于阻塞当前线程
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("关门");
}
}
使用前
可能会在所有人没出去之前关门

使用后
不在乎谁先出去,但是一定要总数等于0后才会关门

原理
countDownLatch.countDown();//总数减1
countDownLatch.await();//等待总数变为0才会往下执行,相当于阻塞当前线程
每次有线程调用countDown() 数量减一,假设计数器变为0,await()就会被唤醒,继续执行!
CyclicBarrier
有减法就有加法

使用方法略有不同,一是添加了达到数量后可以执行一个方法,二十await方法放在了线程的内部
package org.example.demo;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
System.out.println("召唤神龙成功");//在达到数量后运行一个Runnable接口方法
});
for (int i = 1; i <= 7; i++) {
//lambda表达式本质上还是new了一个类,所以无法直接拿到for循环中的变量i,需要通过一个临时变量final来作为一个中间变量来获取到i
final int temp = i;
new Thread(()->{
System.out.println(Thread.currentThread().getName()+":获取到了"+temp+"颗龙珠");
try {
cyclicBarrier.await();//每次等待完成后往下执行,如果达不到数量会死在这
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (BrokenBarrierException e) {
throw new RuntimeException(e);
}
},String.valueOf(i)).start();
}
}
}
Semaphore
Semaphore:信号量

抢车位:6辆车3个车位,123占据了那么456就需要等待,当占据的车走后,那么等待的车就要进入该车位。
用于限流等操作
package org.example.demo;
import java.sql.Time;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SemaphoreDemo {
public static void main(String[] args) {
// 线程数量:限流!让没有得到的等待释放
Semaphore sim = new Semaphore(3);
for (int i = 0; i < 6; i++) {
new Thread(()->{
//acquire 得到
//release 释放
try {
sim.acquire();
System.out.println(Thread.currentThread().getName()+":抢到车位");
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName()+":离开车位");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}finally {//所有需要关闭、释放的操作都放在finally中
sim.release();
}
}).start();
}
}
}
sim.acquire();//得到
sim.release();//释放
作用:多个共享资源互斥的使用!并发限流,控制最大线程数!
JUC并发编程学习笔记(七)常用的辅助类的更多相关文章
- JUC并发编程学习笔记
JUC并发编程学习笔记 狂神JUC并发编程 总的来说还可以,学到一些新知识,但很多是学过的了,深入的部分不多. 线程与进程 进程:一个程序,程序的集合,比如一个音乐播发器,QQ程序等.一个进程往往包含 ...
- 并发编程学习笔记(10)----并发工具类CyclicBarrier、Semaphore和Exchanger类的使用和原理
在jdk中,为并发编程提供了CyclicBarrier(栅栏),CountDownLatch(闭锁),Semaphore(信号量),Exchanger(数据交换)等工具类,我们在前面的学习中已经学习并 ...
- Java并发编程学习笔记
Java编程思想,并发编程学习笔记. 一.基本的线程机制 1.定义任务:Runnable接口 线程可以驱动任务,因此需要一种描述任务的方式,这可以由Runnable接口来提供.要想定义任务,只需实现R ...
- 并发编程学习笔记(15)----Executor框架的使用
Executor执行已提交的 Runnable 任务的对象.此接口提供一种将任务提交与每个任务将如何运行的机制(包括线程使用的细节.调度等)分离开来的方法.通常使用 Executor 而不是显式地创建 ...
- 并发编程学习笔记(14)----ThreadPoolExecutor(线程池)的使用及原理
1. 概述 1.1 什么是线程池 与jdbc连接池类似,在创建线程池或销毁线程时,会消耗大量的系统资源,因此在java中提出了线程池的概念,预先创建好固定数量的线程,当有任务需要线程去执行时,不用再去 ...
- 并发编程学习笔记(13)----ConcurrentLinkedQueue(非阻塞队列)和BlockingQueue(阻塞队列)原理
· 在并发编程中,我们有时候会需要使用到线程安全的队列,而在Java中如果我们需要实现队列可以有两种方式,一种是阻塞式队列.另一种是非阻塞式的队列,阻塞式队列采用锁来实现,而非阻塞式队列则是采用cas ...
- 并发编程学习笔记(11)----FutureTask的使用及实现
1. Future的使用 Future模式解决的问题是.在实际的运用场景中,可能某一个任务执行起来非常耗时,如果我们线程一直等着该任务执行完成再去执行其他的代码,就会损耗很大的性能,而Future接口 ...
- 并发编程学习笔记(12)----Fork/Join框架
1. Fork/Join 的概念 Fork指的是将系统进程分成多个执行分支(线程),Join即是等待,当fork()方法创建了多个线程之后,需要等待这些分支执行完毕之后,才能得到最终的结果,因此joi ...
- 并发编程学习笔记(9)----AQS的共享模式源码分析及CountDownLatch使用及原理
1. AQS共享模式 前面已经说过了AQS的原理及独享模式的源码分析,今天就来学习共享模式下的AQS的几个接口的源码. 首先还是从顶级接口acquireShared()方法入手: public fin ...
- 并发编程学习笔记(8)----ThreadLocal的使用及源码分析
1. ThreadLocal的理解 ThreadLocal,顾名思义,就是线程的本地变量,ThreadLocal会为每个线程创建一个本地变量副本,使得使用ThreadLocal管理的变量在多线程的环境 ...
随机推荐
- 2023-07-17:给定一个数组arr,长度为n, 再给定一个数字k,表示一定要将arr划分成k个集合, 每个数字只能进一个集合。 返回每个集合内部的平均值都累加起来最小的值。 平均值向下取整。 1
2023-07-17:给定一个数组arr,长度为n, 再给定一个数字k,表示一定要将arr划分成k个集合, 每个数字只能进一个集合. 返回每个集合内部的平均值都累加起来最小的值. 平均值向下取整. 1 ...
- CS与反向代理
Cobalt Strike Cobalt Strike是一款基于java的渗透测试神器,常被业界人称为CS神器.自3.0以后已经不在使用Metasploit框架而作为一个独立的平台使用,分为客户端与服 ...
- PHP echo 和 print 语句
在 PHP 中,有两种基本的输出方法:echo 和 print. PHP echo 和 print 语句 echo 和 print 之间的差异: echo - 能够输出一个以上的字符串 print - ...
- Oracle随机生成大数据
Oracle随机插入大数据 话不多说,安排 示例: -- 创建新表并批量插入五千万数据 create table TEST_TAB as select rownum as id, to_char(sy ...
- Linux 软件包:添加repo、升级内核、编译内核、交叉编译
添加 repo 增加 xxx.repo 文件 在/etc/yum.repos.d/目录下创建 add_openeuler_repo.repo 文件 [add_repo] name=add_repo b ...
- windows传输文件到linux
PFSTP 打开该软件,在安装putty自带的 连接服务器 open 192.168.142.131 按提示输入账户密码 传送文件 put C:\Users\13662\nifi-1.13.2-bin ...
- c# 如何将程序加密隐藏?
下面将介绍如何通过LiteDB将自己的程序进行加密,首先介绍一下LiteDB. LiteDB LiteDB是一个轻量级的嵌入式数据库,它是用C#编写的,适用于.NET平台.它的设计目标是提供一个简单易 ...
- c# .NET 高级编程 高并发必备技巧 - 锁
锁 最为常见的应用就是 高并发的情况下,库存的控制.本次只做简单的单机锁介绍. 直接看代码: 每请求一次库存-1. 假如库存1000,在1000个人请求之后,库存将变为0. public int Re ...
- centos7.X安装mysql5.7 – 东凭渭水流
1.下载mysql5.7 可以使用windows下载好后上传至Linux.网络条件好的推荐使用 wget https://dev.mysql.com/get/Downloads/MySQL-5.7/m ...
- JOIN 关联表中 ON、WHERE 后面跟条件的区别
SQL中join连接查询时条件放在on后与where后的区别 数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户. 在使用left jion时,on和wh ...