《Java并发编程实战》课程笔记(十三)

news2024/11/24 7:03:43

并发容器

同步容器及其注意事项

  • Java 中的容器主要可以分为四个大类,分别是 List、Map、Set 和 Queue,但并不是所有的 Java 容器都是线程安全的。
    • 例如,我们常用的 ArrayList、HashMap 就不是线程安全的。
    • 如何将非线程安全的容器变成线程安全的容器?只要把非线程安全的容器封装在对象内部,然后控制好访问路径就可以了。
  • 组合操作需要注意竞态条件问题,即便每个操作都能保证原子性,也并不能保证组合操作的原子性。
    • 在容器领域一个容易被忽视的“坑”是用迭代器遍历容器。
    • 这些经过包装后线程安全容器,都是基于 synchronized 这个同步关键字实现的,所以也被称为同步容器。
    • Java 提供的同步容器还有 Vector、Stack 和 Hashtable,这三个容器不是基于包装类实现的,但同样是基于 synchronized 实现的,对这三个容器的遍历,同样要加锁保证互斥。

并发容器及其注意事项

  • Java 在 1.5 版本之前所谓的线程安全的容器,主要指的就是同步容器。
  • 不过同步容器有个最大的问题,那就是性能差,所有方法都用 synchronized 来保证互斥,串行度太高了。
  • 因此 Java 在 1.5 及之后版本提供了性能更高的容器,我们一般称为并发容器。
    在这里插入图片描述

List

  • List 里面只有⼀个实现类就是 CopyOnWriteArrayList。
    • CopyOnWrite,顾名思义就是写的时候会将共享变量新复制一份出来,这样做的好处是读操作完全无锁。
    • CopyOnWriteArrayList 内部维护了一个数组,成员变量 array 就指向这个内部数组,所有的读操作都是基于 array 进行的,迭代器 Iterator 遍历的就是 array 数组。
      在这里插入图片描述
    • 如果在遍历 array 的同时,还有一个写操作,例如增加元素,CopyOnWriteArrayList 是如何处理的呢?
      • CopyOnWriteArrayList 会将 array 复制一份,然后在新复制处理的数组上执行增加元素的操作,执行完之后再将 array 指向这个新的数组。
      • 读写是可以并行的,遍历操作一直都是基于原 array 执行,而写操作则是基于新 array 进行。
        在这里插入图片描述
  • 使用 CopyOnWriteArrayList 需要注意的“坑”主要有两个方面。
    • 一个是应用场景,CopyOnWriteArrayList 仅适用于写操作非常少的场景,而且能够容忍读写的短暂不一致。
    • 另一个需要注意的是,CopyOnWriteArrayList 迭代器是只读的,不支持增删改。因为迭代器遍历的仅仅是一个快照,而对快照进行增删改是没有意义的。

Map

  • Map 接口的两个实现是 ConcurrentHashMap 和 ConcurrentSkipListMap。
    • 它们从应用的角度来看,主要区别在于 ConcurrentHashMap 的 key 是无序的,而 ConcurrentSkipListMap 的 key 是有序的。
    • 所以如果你需要保证 key 的顺序,就只能使用 ConcurrentSkipListMap。
  • 使用 ConcurrentHashMap 和 ConcurrentSkipListMap 需要注意的地方是,它们的 key 和 value 都不能为空,否则会抛出 NullPointerException 这个运行时异常。
    在这里插入图片描述
  • ConcurrentSkipListMap 的 SkipList 本身就是⼀种数据结构跳表。
    • 跳表插⼊、删除、查询操作平均的时间复杂度是 O(logn),理论上和并发线程数没有关系。
    • 所以在并发度非常高的情况下,若你对 ConcurrentHashMap 的性能还不满意,可以尝试⼀下 ConcurrentSkipListMap。

Set

  • Set 接口的两个实现是 CopyOnWriteArraySet 和 ConcurrentSkipListSet,使用场景可以参考 CopyOnWriteArrayList 和 ConcurrentSkipListMap,它们的原理都是一样的。

Queue

  • Java 并发包里阻塞队列都用 Blocking 关键字标识,单端队列使用 Queue 标识,双端队列使用 Deque 标识。

  • 单端阻塞队列
    在这里插入图片描述

    • 其实现有 ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue、LinkedTransferQueue、PriorityBlockingQueue 和 DelayQueue。
    • 内部一般会持有一个队列,这个队列可以是数组(其实现是 ArrayBlockingQueue)也可以是链表(其实现是 LinkedBlockingQueue);
    • 甚至还可以不持有队列(其实现是 SynchronousQueue),此时生产者线程的入队操作必须等待消费者线程的出队操作。
    • LinkedTransferQueue 融合 LinkedBlockingQueue 和 SynchronousQueue 的功能,性能比 LinkedBlockingQueue 更好;
    • PriorityBlockingQueue 支持按照优先级出队;
    • DelayQueue 支持延时出队。
  • 双端阻塞队列
    在这里插入图片描述

    • 其实现是 LinkedBlockingDeque。
  • 单端非阻塞队列

    • 其实现是 ConcurrentLinkedQueue。
  • 双端非阻塞队列

    • 其实现是 ConcurrentLinkedDeque。
  • 使用队列时,需要格外注意队列是否支持有界(所谓有界指的是内部的队列是否有容量限制)。

    • 实际工作中,一般都不建议使用无界的队列,因为数据量大了之后很容易导致 OOM。
    • 只有 ArrayBlockingQueue 和 LinkedBlockingQueue 是支持有界的,所以在使用其他无界队列时,一定要充分考虑是否存在导致 OOM 的隐患。

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

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

相关文章

java双亲委派机制详解

1. 类加载流程 类加载机制其实就是虚拟机把Class文件加载到内存,并对数据进行校验,转换解析和初始化,形成可以虚拟机直接使用的Java类型,即java.lang.Class。 1.1 装载 Class文件 -- >二进制字节流 -->类加载器 1&#x…

(0.50mm)TF31-4S-0.5SH 4 位置 FFC,FPC 连接器、G846A10221T4EU(1.0MM)矩形连接器 互连器件

TF31-4S-0.5SH (0.50mm)脚距前开盖式FFC/FPC连接器的安装深度为5.7mm,可最大限度地节省电路板空间,并能够自动放置电路板。Hirose Electric TF31连接器具有高FPC保持力(采用FPC侧拉手设计),易于…

Linux下进程及其进程地址空间以及一些进程的控制函数

目录 什么是进程?进程的状态Linux下进程的状态 进程地址空间什么是进程地址空间为什么需要进程地址空间? 进程控制进程控制函数forkwait/waitpid 进程等待进程替换,进程替换函数exe 今天我们来分享一下Linux下的进程和进程地址空间以及一些进…

进出口跨境电商软件平台系统开发,源码技术架构

一、进出口跨境电商软件平台系统开发需做好相应的前期准备,如确定市场、了解政策、推广宣传等。 欢迎名片沟通探讨 确定目标市场:选择合适的目标市场。需要了解目标市场的消费习惯、政策法规以及竞争情况。 了解海关相关政策:针对不同国家或…

python之函数(参数,匿名函数,局部变量和全局变量)

文章目录 前言一、函数的参数 1、形参和实参2、必传参数(也叫:必须参数)3、关键字传参4.、默认参数5、不定长参数6、传参的顺序二、匿名函数(lambda函数) 1. 定义及特点语法格式2. lambda函数的特点三、函数返回值retu…

微信小程序商城开发

随着移动互联网的发展,小程序商城逐渐成为了电商领域的新宠。小程序商城具有便捷、快速、安全等优点,为用户提供了更加优质的购物体验。下面我们来介绍小程序商城的功能和优点。 一、商品展示 小程序商城提供了丰富的商品展示,包括商品分类…

llama_index中query_engine的response_mode详解

文章目录 0. 前言1. ResponseMode: tree_summarize (总结摘要-最优)2. ResponseMode: generation3. ResponseMode: no_text4. ResponseMode: simple_summarize (最省token)5. ResponseMode: refine (基于关键词询问-最…

ROS:坐标管理系统

目录 一、机器人中的坐标变换二、TF功能包2.2TF功能包简介2.2TF坐标变换实现2.3TF案例 三、小海龟跟随实验3.1打开小程序3.2查看当前的TF树3.3坐标相对位置关系可视化1(tf_echo)3.4坐标相对位置关系可视化2(rviz) 一、机器人中的坐…

二、电压源、电流源、受控源

点我回到目录 目录 理想电压源 理想电流源 受控源 电流源做功问题 电压源做功问题 理想电压源 •定义:两端电压保持定值或一定的时间函数,且电压值与流过它的电流i无关 •特点:理想电压源两端的电压由本身决定,与外电路无关…

ChatGPT2论文解读《Language Models are Unsupervised Multitask Learners》(2019)

论文总结 以下是我阅读完整篇论文做的个人总结,包含了ChatGPT-2文章的主要内容,可以仅看【论文总结】章节。 数据集 自制了一个网页爬虫,被抓取的网页部分来自于社交平台,这些网页由人工进行过滤。最终生成WebText数据集&#…

多种工厂模式的运用

文章目录 多种工厂模式的运用一、简单工厂模式(非23种设计模式)1.1 结构2.2 实现2.2.1 简单工厂类图2.2.2 代码2.2.3 优缺点 二、静态工厂模式(非23种设计模式)3.1 代码 三、工厂模式3.1 结构 3.2 实现3.2.1 工厂模式类图3.2.2 代…

Rust教程初识

Rust 教程 Rust 语言是一种高效、可靠的通用高级语言。其高效不仅限于开发效率,它的执行效率也是令人称赞的,是一种少有的兼顾开发效率和执行效率的语言。 Rust 语言由 Mozilla 开发,最早发布于 2014 年 9 月。Rust 的编译器是在 MIT Licens…

bmp图片怎么转jpg格式?思路提供

BMP和JPG是两种常见的图片格式。BMP文件相对较大,无损压缩,而JPG文件则相对较小,有损压缩。当我们需要在保持图片质量的同时减小文件大小时,我们可以将BMP文件转换为JPG文件。在本文中,我们将介绍如何将BMP文件转换为J…

短视频矩阵源码技术开发

短视频矩阵是一种常见的视频编码标准,它通过将视频分成多个小块并对每个小块进行压缩来实现高效的视频传输。在本文中,我们将介绍短视频矩阵的原理和实现,并提供示例代码。 $where_time array(); // 时间 $where_time[] array(name>fbr…

第5章:SpringMVC的视图

一、SpringMVC的视图 SpringMVC中的视图是View接口,视图的作用渲染数据,将模型的Model中的数据展现给用户SpringMVC视图种类很多,默认有转发视图和重定向视图当工程引入jstl依赖,转发视图自动转换为JstlView若使用视图技术是Thym…

【新版】系统架构设计师 - 新老教材对比分析

个人总结,仅供参考,欢迎加好友一起讨论 文章目录 新老教材比较新版教材章节分析 新老教材比较 提示:请自行购买并浏览新版系统架构设计师教材 原教材:2009年出版,共21章,572页。新教材:2022年出…

紧急防勒索病毒的防御方案

一、适用目标(校园网、企业网,windows系列的操作系统): 所有在校园内运行windows系统的电脑,并非只感染服务器操作系统,单机照样感染。会将你电脑中的所有文件全部加密,部分已感染案例有2个共同…

Yolov8轻量级:Next-vit,用于现实工业场景的下一代视觉 Transformer

1.Next-vit介绍 论文:https://arxiv.org/pdf/2207.05501.pdf 由于复杂的注意力机制和模型设计,大多数现有的视觉 Transformer(ViT)在现实的工业部署场景中不能像卷积神经网络(CNN)那样高效地执行。这就带来了一个问题:视觉神经网络能否像 CNN 一样快速推断并像 ViT 一样…

DVPP媒体数据处理图片解码问题案例

DVPP(Digital Vision Pre-Processing)是昇腾AI处理器内置的图像处理单元,通过AscendCL媒体数据处理接口提供强大的媒体处理硬加速能力,主要功能包括图像编解码、视频编解码、图像抠图缩放等。 本期就分享几个关于DVPP图片解码问题…

Web的基本漏洞--越权漏洞

目录 一、越权漏洞介绍 1.越权漏洞的原理 2.越权漏洞的分类 3.越权漏洞产生的原因 一、越权漏洞介绍 越权漏洞指的是应用在检查授权时存在纰漏,可以让攻击者获得低权限用户账户后,利用一些方式绕过权限检查,可以访问或者操作其他用户或者…