线程安全的集合类

news2024/11/26 8:23:26

1.多线程环境使用 ArrayList

1.自己使用同步机制 (synchronized 或者 ReentrantLock)

2.Collections.synchronizedList(new ArrayList); 

  • synchronizedList 是标准库提供的一个基于 synchronized 进行线程同步的 List.
  • synchronizedList 的关键操作上都带有 synchronized
     

3.使用 CopyOnWriteArrayList

  • CopyOnWrite容器即写时复制的容器。
  • 当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,
  • 添加完元素之后,再将原容器的引用指向新的容器

这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会
添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。
优点:
在读多写少的场景下, 性能很高, 不需要加锁竞争.
缺点:
1. 占用内存较多.
2. 新写的数据不能被第一时间读取到
 

2.多线程环境使用队列

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

3.多线程环境使用哈希表

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

  • Hashtable
  • ConcurrentHashMap

1. Hashtable
只是简单的把关键方法加上了 synchronized 关键字.

  

  • 如果多线程访问同一个 Hashtable 就会直接造成锁冲突.
  • size 属性也是通过 synchronized 来控制同步, 也是比较慢的.
  • 一旦触发扩容, 就由该线程完成整个扩容过程. 这个过程会涉及到大量的元素拷贝, 效率会非常低.


2.ConcurrentHashMap
相比于 Hashtable 做出了一系列的改进和优化. 以 Java1.8 为例

  • 读操作没有加锁(但是使用了 volatile 保证从内存读取结果), 只对写操作进行加锁. 加锁的方式仍然是是用 synchronized, 但是不是锁整个对象, 而是 "锁桶" (用每个链表的头结点作为锁对象), 大大降低了锁冲突的概率
  • 充分利用 CAS 特性. 比如 size 属性通过 CAS 来更新. 避免出现重量级锁的情况.
  • 优化了扩容方式: 化整为零
    发现需要扩容的线程, 只需要创建一个新的数组, 同时只搬几个元素过去.
    扩容期间, 新老数组同时存在.
    后续每个来操作 ConcurrentHashMap 的线程, 都会参与搬家的过程. 每个操作负责搬运一小
    部分元素.搬完最后一个元素再把老数组删掉.这个期间, 插入只往新数组加.
    这个期间, 查找需要同时查新数组和老数组.
     

ConcurrentHashMap的读是否要加锁,为什么?

读操作没有加锁. 目的是为了进一步降低锁冲突的概率. 为了保证读到刚修改的数据, 搭配了
volatile 关键字.

介绍下 ConcurrentHashMap的锁分段技术?

这个是 Java1.7 中采取的技术. Java1.8 中已经不再使用了. 简单的说就是把若干个哈希桶分成一个
"段" (Segment), 针对每个段分别加锁.
目的也是为了降低锁竞争的概率. 当两个线程访问的数据恰好在同一个段上的时候, 才触发锁竞争.

ConcurrentHashMap在jdk1.8做了哪些优化?

取消了分段锁, 直接给每个哈希桶(每个链表)分配了一个锁(就是以每个链表的头结点对象作为锁对
象).
将原来 数组 + 链表 的实现方式改进成 数组 + 链表 / 红黑树 的方式. 当链表较长的时候(大于等于
8 个元素)就转换成红黑树.

Hashtable和HashMap、ConcurrentHashMap 之间的区别?

HashMap: 线程不安全. key 允许为 null
Hashtable: 线程安全. 使用 synchronized 锁 Hashtable 对象, 效率较低. key 不允许为 null.
ConcurrentHashMap: 线程安全. 使用 synchronized 锁每个链表头结点, 锁冲突概率低, 充分利用
CAS 机制. 优化了扩容方式. key 不允许为 null






 



 


 

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

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

相关文章

Linux多版本python切换以及多版本pip对应 (cloud studio Ubuntu16.04)

linux && cloud studio && Ubuntu16.04 简单解决多版本python切换以及多版本pip对应问题 1.python2切换成python 多版本python: 更改前先查看版本号 $ python -V Python 2.7.12 $ python2 -V Python 2.7.12 $ python3 -V Python 3.5.2 通过下面的命令看到py…

在传染病中,肠道微生物-免疫力-营养在优化治疗策略中的作用

谷禾健康 传染病,肠道微生物,营养 传染病和感染目前是许多地区尤其是低收入国家主要死亡原因,也是婴儿和老年人等弱势群体的主要风险。免疫系统在这些感染的易感性、持续性和清除中起着至关重要的作用。由于 70-80% 的免疫细胞存在于肠道中&a…

详解子网技术

一 : Internet地址 Intemet实质上是把分布在世界各地的各种网络如计算机局域网和广域网、数字数据通信网以及公用电话交换网等互相连接起来而形成的超级网络。但是 , 网络的物理地址给Internet统一全网地址带来两个方面的问题: 第一,物理地址是物理网络技术的一种…

postman-请求前参数预处理(pre-request)

文章目录一、Pre-request Scrip的简介二、 变量2.1环境变量2.2全局变量2.3动态变量(内置变量)2.4数据变量三、全局变量的定义和使用3.1全局变量的定义3.2全局变量的使用四、动态变量的使用4.1通过界面操作完成Gd变量使用4.2在脚本区写代码调用Pre-reques…

分享113个HTML电子商务模板,总有一款适合您

分享113个HTML电子商务模板,总有一款适合您 113个HTML电子商务模板下载链接:https://pan.baidu.com/s/1JIlnB8qpg4wIuh-fi0e-Bg?pwdiwvr 提取码:iwvr Python采集代码下载链接:采集代码.zip - 蓝奏云 import os import shuti…

Elasticsearch和Solr的区别

背景:它们都是基于Lucene搜索服务器基础之上开发,一款优秀的,高性能的企业级搜索服务器。(是因为他们都是基于分词技术构建的倒排索引的方式进行查询)开发语言:java语言开发诞生时间:Solr2004年…

CAP和BASE理论

CAP理论CAP是 Consistency、Availability、Partition tolerance 三个词语的缩写,分别表示一致性、可用性、分区容忍性。它指出一个分布式计算系统不可能同时满足以下三点:• 一致性(Consistency) :等同于所有节点访问同…

项目管理工具dhtmlxGantt甘特图入门教程(八):数据加载(四)

dhtmlxGantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表,可满足项目管理控件应用程序的所有需求,是最完善的甘特图图表库这篇文章给大家讲解 dhtmlxGantt 的数据属性和数据库结构。 DhtmlxGantt正版试用下载(qun:764…

既生 useState 何生 useReducer (主讲useReducer)

前言 useState 的底层其实是用useReducer 实践的 useReducer 适合较复杂的state,因为我们可以将状态的改变统一放在reducer 去做管理,像useState 的状态改变就会分散在不同的函式里面。 语法 const [state, dispatch] = useReducer(reducer, initialState, initStateFn)use…

【蓝桥杯选拔赛真题37】python判断自守数 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析

目录 python判断自守数 一、题目要求 1、编程实现 2、输入输出 二、解题思路

后台开发常见层式结构设计:时间轮、跳表、LSM_Tree

目录1、海量并发定时任务:时间轮2、高并发读写有序结构组织;跳表3、空间利用率以及写性能高的磁盘数据组织:LSM_Tree时间轮:内核定时器的实现、skynet、kafka、netty; 跳表:redis、rocksdb LSM-Tree:写多读…

SpringCloud学习笔记 - 自定义及解耦降级处理方法 - Sentinel

1. SentinelRecourse配置回顾 通过之前的学习,我们知道SentinelRecourse配置的资源定位可以通过两种方式实现:一种是URL,另一种是资源名称。这两种限流方式都要求资源ID唯一 RestController public class RateLimitController {GetMapping(…

MySQL -查询日志、二进制日志、错误日志、慢查询日志

文章目录1.错误日志2.二进制日志3.查询日志4.慢查询日志1.错误日志 错误日志是 MySOL中最重要的日志之一,它记录了当 mvsald 启动和停止时,以及服务器在运行过程中发生任何严重错误时的相关信息当数据库出现任何故障导致无法正常使用时,建议…

龙曲良 Tensorflow —— 神经网络与全连接层(自用)

目录 一、数据加载(keras.datasets) 1.1 MNIST 加载 1.2 CIFAR10/100 加载 1.3 tf.data.Dataset.from_tensor_slices 1.4 .shuffle (对应打散数据) 1.5 .map(数据预处理) 1.6 .batch / .repeat 二…

vue3语法

vue3教程 //ps 这里是基本写法 一般项目不需要ref 因为需要一直return 这里是根据在不使用ts后缀 来在.vue里面写setup 如下图所示:setup setup是启动页面会自动执行的一个函数 项目里定义的所有变量,都要在setup当中 在setup定义的变量和方法,都需要r…

chatGTP的全称Chat Generative Pre-trained Transformer

chatGPT,有时候我会拼写为:chatGTP,所以知道这个GTP的全称是很有用的。 ChatGPT全名:Chat Generative Pre-trained Transformer ,中文翻译是:聊天生成预训练变压器,所以是GPT,G是生…

DIDL3_模型选择、复杂度、过欠拟合的相关概念

模型选择、复杂度、过欠拟合的概念模型选择训练误差和泛化误差验证数据集和测试数据集K-则交叉验证(没有足够多数据时使用)过拟合和欠拟合模型容量模型容量的影响估计模型容量控制模型容量数据复杂度处理过拟合的方法(1)&#xff…

关于最近大热的AI,你怎么看?

AI人工智能,相信大家都不陌生,也都接触过不少。但是最近小编在网上冲浪的时候发现各大媒体又掀起了一阵AI热潮,AI不是很常见了吗?是又有什么新的发展吗? 带着强烈的好奇心,我在地铁上读完了一篇关于Chatgp…

【分享】如何通过集简云将ChatGPT人工智能接入到您的内容平台中?

ChatGPT是一款非常强大的人工智能产品,可以有创造性的回复和创作文字,图片,适用于很多办公场景。这篇文章将介绍如何将ChatGPT接入到您的办公系统中。 目前集简云提供了两个ChatGPT应用: OpenAI(ChatGPT)内置:这个是集…

IB化学考什么?这些知识点请收藏

春天来了,IB大考还会远吗?不少学生为IB大考紧张不已。为大家介绍一下IB化学的相关内容。01考试时间和考试形式 2023年IB考试将于2023年4月27日开始,2023年5月19日结束。化学部分的考试分别是在5月11日、12日进行。 IB化学考试包括&#xff1a…