【JavaEE初阶】线程安全的集合类
📕 引言
我们之前讲过的集合类,,大部分都不是线程安全的.
Vector, Stack, HashTable, 是线程安全的(都是自带了synchronized,不建议用), 其他的集合类不是线程安全的。
注意:加锁不能保证线程一定安全,不加锁也不能确定线程一定不安全,具体代码具体分析
为什么不建议使用呢?
因为我们在使用的时候,这些类就会自动的加锁,虽然编译器会自动优化为没有锁竞争的线程进行锁消除的优化,但是呢万一编译器没有优化好,就麻烦了

如果需要用到其他的类,就需要手动加锁,来保证线程安全(不同情况加锁方式也不同)
🌲多线程环境使用 ArrayList
🚩自己使用同步机制 (synchronized 或者 ReentrantLock)
这里就不在过多讲述了
🚩Collections.synchronizedList(new ArrayList);
-
synchronizedList 是标准库提供的一个基于 synchronized 进行线程同步的List.
-
synchronizedList 的关键操作上都带有 synchronized
相当于给ArrayList这些集合类,套一层壳,壳上是给关键方法都加了synchronized
🚩使用 CopyOnWriteArrayList
也是一种解决线程安全的问题的做法
使用CopyOnWrite容器即"写时拷贝"的容器
-
当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,
-
添加完元素之后,再将原容器的引用指向新的容器
例子:

这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。
所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。
优点:
- 在读多写少的场景下, 性能很高, 不需要加锁竞争.
缺点:
-
占用内存较多.
-
新写的数据不能被第一时间读取到
🎍多线程环境使用队列
这里简单讨论一下即可,前面讨论过。
-
ArrayBlockingQueue
基于数组实现的阻塞队列 -
LinkedBlockingQueue
基于链表实现的阻塞队列 -
PriorityBlockingQueue
基于堆实现的带优先级的阻塞队列 -
TransferQueue
最多只包含一个元素的阻塞队列
🎋多线程环境使用哈希表
HashMap 本身不是线程安全的.
在多线程环境下使用哈希表可以使用:
-
Hashtable(自带锁,只是线程比较安全,但不推荐使用)
-
ConcurrentHashMap(多线程使用哈希表,优先考虑这个)
🚩Hashtable
Hashtable在实现过程中只是简单的把关键方法加上了 synchronized 关键字.
观察源码即可:(就不一一展示了)
![]()
这相当于直接针对 Hashtable 对象本身加锁.
-
如果多线程访问同一个 Hashtable 就会直接造成锁冲突.
-
size 属性也是通过 synchronized 来控制同步, 也是比较慢的.
-
一旦触发扩容, 就由该线程完成整个扩容过程. 这个过程会涉及到大量的元素拷贝, 效率会非常低

🚩ConcurrentHashMap
相比于 Hashtable 做出了一系列的改进和优化.
1.使用"锁桶"的方式,来代替"一把全局锁",有效的降低锁冲突的概率


2.HashMap的size,即使你插入的的元素是不同的链表上的元素,也会涉及到多个线程针对同一size变量进行修改。
引入 CAS ,通过 CAS 的方式来修改size,也就避免了加锁操作。也可进一步的提升效率
3.针对扩容操作的优化

核心思路:"化整为零"

注意:
ConcurrentHashMap 是一个工作中非常常用,面试非常高频的问题!!!整个多线程进行部分,哪怕别的不记得,这个一定记得。
细节:

🌳相关面试题
1.ConcurrentHashMap的读是否要加锁,为什么?
读操作没有加锁. 目的是为了进一步降低锁冲突的概率. 为了保证读到刚修改的数据, 搭配了 volatile 关键字.
2.介绍下 ConcurrentHashMap的锁分段技术?
这个是 Java1.7 中采取的技术. Java1.8 中已经不再使用了. 简单的说就是把若干个哈希桶分成一个 “段” (Segment),针对每个段分别加锁. 目的也是为了降低锁竞争的概率. 当两个线程访问的数据恰好在同一个段上的时候, 才触发锁竞争.
3.ConcurrentHashMap在jdk1.8做了哪些优化?
取消了分段锁, 直接给每个哈希桶(每个链表)分配了一个锁(就是以每个链表的头结点对象作为锁对 象). 将原来 数组 + 链表的实现方式改进成 数组 + 链表 / 红黑树 的方式. 当链表较长的时候(大于等于 8 个元素)就转换成红黑树.
4.Hashtable和HashMap、ConcurrentHashMap 之间的区别?
- HashMap: 线程不安全. key 允许为 null
- Hashtable: 线程安全. 使用 synchronized 锁,Hashtable 对象, 效率较低. key 不允许为 null.
- ConcurrentHashMap: 线程安全. 使用synchronized 锁每个链表头结点, 锁冲突概率低, 充分利用 CAS 机制. 优化了扩容方式. key 不允许为 null
相关文章:
【JavaEE初阶】线程安全的集合类
📕 引言 我们之前讲过的集合类,,大部分都不是线程安全的. Vector, Stack, HashTable, 是线程安全的(都是自带了synchronized,不建议用), 其他的集合类不是线程安全的。 注意:加锁不能保证线程一定安全,不加锁也不能确定线程一定…...
关于Vue项目npm快捷键,点击run启动报错,及npm i也报错的解决办法
1.配置idea的npm 2.点击运行按钮 3.结果 分析原因及问题: npm i npm run dev 由于是刚刚从gitlab新拉的前端代码,可能没有用命令install过类似于没有编译过,所以执行一下上面的命令 结果报错如下: F:\tbyf\qjyy\hip-manager-ui&…...
React中,className属性自定义组件不生效的问题
在React中,className属性不仅适用于原生的HTML元素,也可以用于自定义组件。实际上,className属性是React中通用的属性,可以应用于任何React元素,无论是原生的HTML元素还是自定义的组件。 为什么使用className而不是cl…...
Ubuntu22.04搭建fabric开发环境、开发环境下运行链码
在智能合约开发过程中,开发人员需要一种快速、迭代地测试链码包的方法,而无需为每次修改运行链码生命周期命令。 使用 Fabric 二进制文件并启动peer处于开发模式(“DevMode”),然后将链码连接到peer。它允许您启动链代…...
[BSidesCF 2019]Kookie1
打开题目,看到 根据提示,账号:cookie。密码:monster。试一下登录,登陆成功 抓包看看信息 根据提示, 看一下返回包 账号要加username要改成admin,改一下试试 构造cookie 直接得到flag flag{c…...
LCM红外小目标检测
根据站内的matlab代码修改成python版本。 import numpy as np import matplotlib.pyplot as plt import cv2 from pylab import mpl# 设置中文显示字体 mpl.rcParams["font.sans-serif"] ["SimHei"]def LCM_computation(patch_LCM_in):row, col patch_L…...
振德医疗选择泛微千里聆RPA,助力电商、人事业务流程自动化
振德医疗用品股份有限公司成立于1994年,中国A股上市公司,是医用敷料和感控防护产品主要的供应商之一。 (图片素材来自振德医疗官网) 振德医疗的业务在线上线下齐发力。目前拥有5个国内生产基地,3个海外工厂࿰…...
VBA高级应用30例应用3在Excel中的ListObject对象:创建表
《VBA高级应用30例》(版权10178985),是我推出的第十套教程,教程是专门针对高级学员在学习VBA过程中提高路途上的案例展开,这套教程案例与理论结合,紧贴“实战”,并做“战术总结”,以…...
IP 地址在 SQL 注入攻击中的作用及防范策略
数据库在各个领域的逐步应用,其安全性也备受关注。SQL 注入攻击作为一种常见的数据库攻击手段,给网络安全带来了巨大威胁。今天我们来聊一聊SQL 注入攻击的基本知识。 SQL 注入攻击的基本原理 SQL 注入是通过将恶意的 SQL 代码插入到输入参数中…...
Unity VR黑屏
picosdk里面的,有修改 using System.Collections; using System.Collections.Generic; using UnityEngine;public class ScreenFade : MonoBehaviour {[Tooltip("颜色")]public Color fadeColor new Color(0.0f, 0.0f, 0.0f, 1.0f);private int renderQ…...
Vue.js 中使用 Watcher 的强大场景和案例
目录 表单验证 示例代码: HTML: 获取 API 数据 示例代码: HTML: 深度监听对象变化 示例代码: HTML: 观察多个数据源 示例代码: HTML: Vue.js 是一个流行的前端框架,以其直观的数据绑定和组件驱动的开发模式而闻名。其中,watch 功能是其响应式编程模型…...
《实现 DevOps 平台(2) · GitLab CI/CD 交互》
📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…...
【机器学习sklearn实战】岭回归、Lasso回归和弹性网络
一 sklean中模型详解 1.1 Ride regression 1.2 Lasso regression 1.3 ElasticNet 二 算法实战 2.1 导入包 import numpy as np import pandas as pd from sklearn import datasets from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.linear…...
Python 爬虫项目实战六:抓取猫眼电影排行榜的数据
在这篇博客中,我们将通过一个实际的Python爬虫项目,详细讲解如何抓取网页数据。本次选择的实战项目是抓取猫眼电影排行榜的数据,通过这个项目,你将学会如何使用Python编写爬虫,从网页中提取有用的电影信息。 一、项目…...
YOLO系列:从yolov1至yolov8的进阶之路 持续更新中
一、基本概念 1.YOLO简介 YOLO(You Only Look Once):是一种基于深度神经网络的对象识别和定位算法,其最大的特点是运行速度很快,可以用于实时系统。 2.目标检测算法 RCNN:该系列算法实现主要为两个步骤&…...
欧拉系统离线安装界面ukui
1、官网下载安装镜像iso后,默认没有gui openEuler | 开源社区 | openEuler社区官网openEuler是一个开源、免费的 Linux 发行版平台,将通过开放的社区形式与全球的开发者共同构建一个开放、多元和架构包容的软件生态体系。同时,openEuler 也是…...
Milvus向量数据库的简介以及用途
Milvus 是一个开源的向量数据库,专门用于处理和存储高维向量数据。它可以高效地支持各种数据科学和机器学习应用,特别是在涉及到大规模相似度搜索和推荐系统等领域。 以下是 Milvus 的简介以及它的主要用途。 1. Milvus 简介 Milvus 是由 Zilliz 开发的开源分布式向量数据库…...
恒创科技:IPv4 和 IPv6 之间的主要区别
IPv4 和 IPv6 是互联网协议 (IP) 系统中使用的两种版本的 IP 地址格式。虽然它们的主要目的是准确识别、发送和接收互联网上的数据,但 IPv4 和 IPv6 之间存在许多关键差异。 地址格式 IPv4 采用 32 位格式,由 4 个数值(称为八位字节)表示,以点…...
TinyWebserver的复现与改进(1):服务器环境的搭建与测试
计划开一个新坑, 主要是复现qinguoyi/TinyWebServer项目,并且使用其它模块提升性能。 本文开发服务器配置:腾讯云轻量级服务器,CPU - 2核 内存 - 2GB,操作系统 Ubuntu Server 18.04.1 LTS 64bit 打开端口 需要打开服务器3306、80…...
【Python】练习题附带答案
1、使用for循环实现输出9*9乘法表 代码: 2、写代码实现累乘计算器。 示例:用户输入:5*9*87输出答案:3915 代码: 3、写代码实现,循环提示用户输入的内容(Q/q终止循环),…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...
【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)
旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据!该数据集源自2025年4月发表于《地理学报》的论文成果…...
麒麟系统使用-进行.NET开发
文章目录 前言一、搭建dotnet环境1.获取相关资源2.配置dotnet 二、使用dotnet三、其他说明总结 前言 麒麟系统的内核是基于linux的,如果需要进行.NET开发,则需要安装特定的应用。由于NET Framework 是仅适用于 Windows 版本的 .NET,所以要进…...
路由基础-路由表
本篇将会向读者介绍路由的基本概念。 前言 在一个典型的数据通信网络中,往往存在多个不同的IP网段,数据在不同的IP网段之间交互是需要借助三层设备的,这些设备具备路由能力,能够实现数据的跨网段转发。 路由是数据通信网络中最基…...
Tauri2学习笔记
教程地址:https://www.bilibili.com/video/BV1Ca411N7mF?spm_id_from333.788.player.switch&vd_source707ec8983cc32e6e065d5496a7f79ee6 官方指引:https://tauri.app/zh-cn/start/ 目前Tauri2的教程视频不多,我按照Tauri1的教程来学习&…...
