JUC(Java.util.concurrent)的常见类

目录

♫ReentrantLock

♪什么是ReentrantLock

♪ReentrantLock的用法

♪ReentrantLock和synchronized的区别

♫Semaphore

♪什么是Semaphore

♪semaphore的用法

♫CountDownLatch

♪什么是CountDownLatch

♪CountDownLatch的使用

♫多线程环境使用ArrayList

♫多线程环境使用队列

♫多线程环境使用哈希表


JUC除了提供前面介绍过的线程池、定时器,还提供了多线程编程中其它一些常用的工具类和接口(ReentrantLock、Semaphore、CountDownLatch等)

♫ReentrantLock

♪什么是ReentrantLock

ReentrantLock 是 Java 标准库提供的一种可重入互斥锁 synchronized 定位类似,都是用来实现互斥效果,保证线程安全的。

♪ReentrantLock的用法

使用 ReentrantLock 需要使用  lock()  加锁, 如果获取不到锁就死等)或  trylock(超时时间)加锁, 如果获取不到锁, 等待一定的时间之后就放弃加锁)和  unlock()解锁)对代码块进行加锁解锁:
.
ReentrantLock reentrantLock = new ReentrantLock();
reentrantLock.lock();
//加锁内容
reentrantLock.unlock();

为了避免加锁内容提前退出(有return语句或异常),导致没有执行到 unlock() 语句,一般搭配 try-finally 语句执行加锁加锁操作:

ReentrantLock reentrantLock = new ReentrantLock();
try {reentrantLock.lock();//加锁内容
} finally {reentrantLock.unlock();
}

♪ReentrantLock和synchronized的区别

. synchronized 是一个关键字, JVM 内部实现的 ( 大概率是基于 C++ 实现 );ReentrantLock 是标准库的一个类, JVM 外实现的 ( 基于 Java 实现 )。
. synchronized 使用时不需要手动释放锁; ReentrantLock 使用时需要手动释放。
. synchronized 在申请锁失败时, 会死等; ReentrantLock 可以通过 trylock 的方式等待一段时间就放弃。
. synchronized 是非公平锁; ReentrantLock 默认是非公平锁,也 可以通过构造方法传入一个 true 开启公平锁模式。
. synchronized 是通过 Object wait / notify 实现等待 - 唤醒, 每次唤醒的是一 个随机等待的线程;  ReentrantLock 搭配 Condition 类实现等待 - 唤醒, 可以更精确控制唤醒某个指 定的线程。

♫Semaphore

♪什么是Semaphore

Semaphore 是信号量的意思,用来表示 "可用资源的个数",其本质上就是一个计数器。

例如:图书馆有500个空位,学生扫码入座,可用座位-1(相当于信号量的P操作),学生扫码离座,可用座位+1(相当于信号量的V操作),如果座位为0,就无法再扫码入座了(阻塞等待)。

注:Semaphore 的 PV 操作中的加减计数器操作都是原子的,可以在多线程环境下直接使用

♪semaphore的用法

semaphore 通过传递的参数确定总资源个数,通过 acquire() 方法申请资源(P操作),通过release() 方法释放资源(V操作):

import java.util.concurrent.Semaphore;public class Test {public static void main(String[] args) {//初始值为3的信号量Semaphore semaphore = new Semaphore(3);Runnable runnable = new Runnable() {@Overridepublic void run() {try {//申请资源semaphore.acquire();Thread.sleep(100);//释放资源semaphore.release();} catch (InterruptedException e) {throw new RuntimeException(e);}}};//10个线程都尝试获取资源for (int i = 0; i < 10; i++) {Thread thread = new Thread(runnable);thread.start();}}
}

♫CountDownLatch

♪什么是CountDownLatch

CountDownLatch 用于同时等待 N 个任务执行结束, 好像跑步比赛,10个选手依次就位,哨声响才同时出发;所有选手都通过终点,才能公布成绩。

♪CountDownLatch的使用

CountDownLatch   通过传递参数确认需要完成的 任务个数,每个任务执行完毕, 都调用 countDown() 方法,在 CountDownLatch 内部的计数器同时自减,主线程中使用 await(),只有当计数器减为0时调用 countDown() 方法才会唤醒await():
import java.util.concurrent.CountDownLatch;public class Test {public static void main(String[] args) throws InterruptedException {CountDownLatch countDownLatch = new CountDownLatch(10);Runnable runnable = new Runnable() {@Overridepublic void run() {try {Thread.sleep(100);countDownLatch.countDown();} catch (InterruptedException e) {throw new RuntimeException(e);}}};for (int i = 0; i < 10; i++) {Thread thread = new Thread(runnable);thread.start();}countDownLatch.wait();}
}

♫多线程环境使用ArrayList

在多线程环境下,直接使用ArrayList往往会出现线程安全问题,我们可以通过一下几点方案解决该问题:

♩.自己使用同步机制(synchronized 或者 ReentrantLock)进行加锁

♩.使用Collections.synchronizedList(new ArrayList) synchronizedList 是标准库提供的一个基于 synchronized 进行线程同步的 List,synchronizedList 的关键操作上都带有 synchronized。
.使用 CopyOnWriteArrayList
CopyOnWrite容器即写时拷贝的容器,当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行拷贝, 复制出一个新的容器,然后在新的容器里添加元素,
添加完元素之后,再将原容器的引用指向新的容器。 这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。

♫多线程环境使用队列

.ArrayBlockingQueue :基于数组实现的阻塞队列
.LinkedBlockingQueue :基于链表实现的阻塞队列
.PriorityBlockingQueue :基于堆实现的带优先级的阻塞队列
.TransferQueue :最多只包含一个元素的阻塞队列

♫多线程环境使用哈希表

 HashMap 本身不是线程安全的,在多线程环境下使用哈希表可以使用Hashtable和ConcurrentHashMap。

♩.Hashtable:只是简单的把关键方法加上了 synchronized 关键字,一个Hashtable只有一把锁,两个线程访问Hashtable中的任何数据都会出现锁竞争。

.ConcurrentHashMap

ConcurrentHashMap 相比于 Hashtable 做出了一系列的改进和优化,大大缩小了锁冲突的概率(把一大锁转换成好几把小锁)。
①. ConcurrentHashMap的做法是对每个链表分别进行加锁,这样子操作不同链表里的元素就不会发生锁冲突, 大大降 低了锁冲突的概率。
②. ConcurrentHashMap对读操作不加锁,而是 使用了 volatile 保证从内存读取结果,避免了读和写之间读到写了一半的数据。
③. ConcurrentHashMap充分利用 CAS 特性( 比如 size 属性通过 CAS 来更新), 避免出现重量级锁的情况。
④. ConcurrentHashMap优化了扩容方式,即化整为零:发现需要扩容的线程,只需要创建一个新的数组, 同时只搬几个元素过去,扩容期间, 新老数组同时存在,后续每个来操作 ConcurrentHashMap 的线程, 都会参与搬家的过程, 每个操作负责搬运一小部分元素,搬完最后一个元素再把老数组删掉。这个期间, 插入只往新数组加, 查找需要同时查新数组和老数组。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/177911.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在Excel表格中找回密码

最简单的excel表格解密方法是通过密码帝官网。具体步骤如下&#xff1a;第一步百度搜索【 密码帝官网 】&#xff0c;第二步在用户中心上传需要解密的文件即可。 这个方法安全且简单易操作&#xff0c;不用下载软件&#xff0c;适用于手机和电脑。如果你的excel表格不能编辑&a…

数据分享 I 重点城市现状建筑数据,shp格式放送

数据名称: 现状建筑数据 数据格式: Shp 数据时间: 不同城市的数据时间有所不同&#xff0c;详情可搜“吧唧数据” 数据几何类型: 面 数据坐标系: WGS84坐标系 数据来源&#xff1a;网络公开数据 深圳市现状建筑数据示意图 东莞市部分镇街现状建筑数据示意图 武汉市部…

深入了解MySQL数据库管理与应用

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 当涉及MySQL数据库管理与应用时&#xff0c;深…

【Cisco Packet Tracer】构造超网

​​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《Cisco Packet Tracer | 奇遇记》⏰寄 语&#xff1a;风翻云浪激&#xff0c;剑舞星河寂。 临风豪情壮志在&#xff0c;拨云见日昂首立。 目录 ⛳️1. Cisco Packet Trace…

在数据库中进行表内容的修改(MYSQL)

根据表中内容&#xff0c;用命令语句创建数据库&#xff0c;表格&#xff0c;以及插入&#xff0c;修改&#xff0c;删除表格中的内容。 创建数据库&#xff1a;zrzy mysql> create database zrzy; 引用zrzy数据库&#xff1a; mysql> use zrzy; 创建student_info表&…

vulnhub靶机gigachad_vh

下载地址&#xff1a;Gigachad: 1 ~ VulnHub 主机发现 目标166 端口扫描 端口服务扫描 漏洞扫描 这玩意多得离谱 于是我用a重新扫了一遍 先去看web (⊙﹏⊙)离谱&#xff0c;目录扫描&#xff08;之前先去看一下nmap扫到的html&#xff09; 后面扫描的目录奇多&#xff0c;而…

NX二次开发UF_MTX3_x_vec 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_MTX3_x_vec Defined in: uf_mtx.h void UF_MTX3_x_vec(const double mtx [ 9 ] , double x_vec [ 3 ] ) overview 概述 Returns the X-direction vector of a matrix. 返回矩阵…

人工智能的崭新时代:科技魔术的开始

人工智能&#xff0c;如同一位魔术师&#xff0c;已经在我们的生活中施展出了惊人的魔法。从智能手机到智能家居&#xff0c;人工智能不仅令我们的生活更为便捷&#xff0c;更让我们体验到科技的魅力。 1. 智能手机&#xff1a;随身的智慧助手 智能手机是人工智能最为广泛应用…

vue2.js添加水印

通过canvas生成水印图片 function addWaterMark(str) {let ctx document.createElement("canvas");ctx.width 900;ctx.height 450;ctx.style.display "none";let cans ctx.getContext("2d");cans.rotate((-20 * Math.PI) / 180);cans.font…

TMUX设置鼠标滚轮滑动来浏览之前的前面内容--复制文字

在Ubuntu上使用Tmux有时使用鼠标滚轮时&#xff0c;和平时使用终端的习惯不怎么一致&#xff0c;因此可以设置启用鼠标滚轮。 通过鼠标滚轮滑动来浏览之前的前面内容 具体方式&#xff1a; 1 按完前缀ctrlB后 2 再按冒号&#xff1a;(记得shift) 3 进入命令行模式(下方绿色栏变…

Bootstrap v5版本的HTML模板

一个基本的Bootstrap v5版本的HTML模板。这是一个非常基础的模板&#xff0c;包含了Bootstrap CSS和JS的引用&#xff0c;以及一个基本的HTML结构。 <!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"UTF-8"> <…

uniapp地图基本使用及解决添加markers不生效问题?

uniapp地图使用 App端 通过 nvue 页面实现地图 文章目录 uniapp地图使用效果图templatejs添加 marker使用地图查看位置移到到当前位置 效果图 template <template><view class"mapWrap"><!-- #ifdef APP-NVUE --><map class"map-containe…

springboot自定义更换启动banner动画

springboot自定义更换启动banner动画 文章目录 springboot自定义更换启动banner动画 &#x1f4d5;1.新建banner&#x1f5a5;️2.启动项目&#x1f516;3.自动生成工具&#x1f9e3;4.彩蛋 &#x1f58a;️最后总结 &#x1f4d5;1.新建banner 在resources中新建banner.txt文…

my.ini添加了一句后又删除了,重启却失败的解决办法

背景&#xff1a;添加了一句&#xff0c;然后保存了&#xff0c;之后打开删掉了&#xff0c;结果就无法启动了&#xff0c;最后另存为ANSI格式&#xff0c;再把这个格式文件覆盖my.ini即可解决

商品软文怎么写?媒介盒子教你三步

想要把产品卖出去&#xff0c;除了保证产品质量外&#xff0c;还可以通过线上推广来提高产品销量&#xff0c;而商品文案就是线上推广中的重要因素&#xff0c;今天媒介盒子就来和大家聊聊&#xff0c;怎么写好商品软文。 商品软文想要写好主要分为三要素&#xff1a;痛点、卖…

pytdx 分笔 数据

pytdx 分笔 数据 https://rainx.gitbooks.io/pytdx/content/pytdx_hq.html 「 通达信 」的基本使用及常用设置 https://zhuanlan.zhihu.com/p/558652417 通达信功能介绍&#xff1a;还没用过“超级盘口”&#xff1f;你损失大了&#xff01; https://baijiahao.baidu.com/s?i…

C++相关闲碎记录(1)

1、C绘制爱心图像 #include <iostream> #include <cmath>using namespace std;int main() {// 心形曲线公式 (x^2 y^2 - a)^3 - x^2*y^3 0double a 1;double bound 1.5 * sqrt(a);double step 0.05;for (double y bound; y > -bound; y - step) {for (do…

方案开发:车载吸尘器PCBA方案

车载吸尘器PCBA方案&#xff0c;是为满足汽车内部清洁需求而设计的一种便携式吸尘器方案。随着人们对汽车内部环境卫生的要求日益提高&#xff0c;传统的手动清洁方式已经无法满足需求。因此&#xff0c;研发出一种便携式吸尘器方案&#xff0c;成为了刚性需求。 汽车便携吸尘…

GAN:GAN论文学习

论文&#xff1a;https://arxiv.org/pdf/1406.2661.pdf 发表&#xff1a;2014 一、GAN简介&#xff1a;Generative Adversarial Network GAN是由Ian Goodfellow于2014年提出&#xff0c;GAN&#xff1a;全名叫做生成对抗网络。GAN的目的就是无中生有&#xff0c;以假乱真。 …

3. 迷宫问题

一.题干 迷宫有一个入口&#xff0c;一个出口。一个人从入口走进迷宫&#xff0c;目标是找到出口。阴影部分和迷宫的外框为墙&#xff0c;每一步走一格&#xff0c;每格有四个可走的方向&#xff0c;探索顺序为地图方向&#xff1a;南&#xff08;下&#xff09;、东&#xff0…