Java之并发编程(三)

news2024/11/18 6:31:53

五、Java 常见并发容器总结

1.ConcurrentHashMap

ConcurrentHashMap : 线程安全的 HashMap

1.1 Collections.synchronizedMap()

并发时使用它方法包装HashMap同步,这属于全局锁,性能低下。

1.2 ConcurrentHashMap,

读写操作都能保证很高的性能
(1)在进行读操作时(几乎)不需要加锁

(2)写操作时通过锁分段技术,只对所操作的段加锁,而不影响客户端对其他段的访问。

2.CopyOnWriteArrayList

** 线程安全的 List,在读多写少的场合性能非常好,远远好于 Vector。**

2.1 写完全不加锁,写写加锁

写入也不会堵塞读取操作,只有写入和写入之间需要进行同步等待

2.2 如何实现?

所有可变操作(add,set 等等)都是通过创建底层数组的新副本来实现的。

(1)当需要修改时,并不修改原来数据,而是复制一份副本并对副本修改

(2)修改完完后,副本替换原来的数据

2.3 读取和写入源码简单分析

2.3.1 读取

读取操作没有任何同步控制和锁操作,理由就是内部数组 array 不会发生修改,只会被另外一个 array 替换,因此可以保证数据安全。

   /** The array, accessed only via getArray/setArray. */
    private transient volatile Object[] array;
    public E get(int index) {
        return get(getArray(), index);
    }
    @SuppressWarnings("unchecked")
    private E get(Object[] a, int index) {
        return (E) a[index];
    }
    final Object[] getArray() {
        return array;
    }

2.3.2 写入

写入操作 add()方法在添加集合的时候加了锁,保证了同步,避免了多线程写的时候会 copy 出多个副本出来。

 /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return {@code true} (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        final ReentrantLock lock = this.lock;
        lock.lock();//加锁
        try {
            Object[] elements = getArray();
            int len = elements.length;
            Object[] newElements = Arrays.copyOf(elements, len + 1);//拷贝新数组
            newElements[len] = e;
            setArray(newElements);
            return true;
        } finally {
            lock.unlock();//释放锁
        }
    }

3.ConcurrentLinkedQueue

高效的并发队列,使用链表实现。可以看做一个线程安全的 LinkedList,这是一个非阻塞队列。

(1)主要使用 CAS 非阻塞算法来实现线程安全

(2)适合在对性能要求相对较高,同时对队列的读写存在多个线程同时进行的场景,即如果对队列加锁的成本较高则适合使用无锁的 ConcurrentLinkedQueue 来替代。

4.BlockingQueue

** 这是一个接口,JDK 内部通过链表、数组等方式实现了这个接口。表示阻塞队列,非常适合用于作为数据共享的通道。**

4.1 应用于“生产者-消费者”,提供了可阻塞的插入和移除的方法。

(1)当队列容器已满,生产者线程会被阻塞,直到队列未满;

(2)当队列容器为空时,消费者线程会被阻塞,直至队列非空时为止。

4.2 常见实现类

4.2.1 ArrayBlockingQueue

(1)有界队列实现类,底层采用数组来实现。

(2)并发控制采用可重入锁 ReentrantLock ,读写都需要获取到锁才能进行操作

(3)队列容量满时放入元素队列操作将会阻塞;队列空时中取元素也同样会阻塞。

(4)默认非公平性队列

(5)可改成公平性队列,但会降低吞吐量,如下:

private static ArrayBlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(10,true);

4.2.2 LinkedBlockingQueue

(1)底层基于单向链表实现的阻塞队列,既可作为有界队列也可作为无界队列

(2)比ArrayBlockingQueue 具有更高的吞吐量

(3)创建时指定大小防止容量速增,降低内存消耗,否则容量为Integer.MAX_VALUE。

构造方法如下:

 /**
     *某种意义上的无界队列
     * Creates a {@code LinkedBlockingQueue} with a capacity of
     * {@link Integer#MAX_VALUE}.
     */
    public LinkedBlockingQueue() {
        this(Integer.MAX_VALUE);
    }

    /**
     *有界队列
     * Creates a {@code LinkedBlockingQueue} with the given (fixed) capacity.
     *
     * @param capacity the capacity of this queue
     * @throws IllegalArgumentException if {@code capacity} is not greater
     *         than zero
     */
    public LinkedBlockingQueue(int capacity) {
        if (capacity <= 0) throw new IllegalArgumentException();
        this.capacity = capacity;
        last = head = new Node<E>(null);
    }

4.2.3 PriorityBlockingQueue

(1)支持优先级的无界阻塞队列,相当于 PriorityQueue 的线程安全版本

(2)默认元素自然排序,可自定义类实现 compareTo() 方法来指定元素排序规则,或者初始化时通过构造器参数 Comparator 来指定排序规则。

(3)并发控制采用可重入锁 ReentrantLock,为无界队列

(4)不可以插入 null,插入队列的对象必须是可比较大小的(comparable),否则报 ClassCastException 异常。

(5)插入操作 put 方法不会 block,因为它是无界队列(take 方法在队列为空的时候会阻塞)。

5.ConcurrentSkipListMap

** 跳表的实现。这是一个 Map,使用跳表的数据结构进行快速查找。**

(1)跳表的本质是同时维护了多个链表,并且链表是分层的

(2)最低层的链表维护了跳表内所有的元素,每上面一层链表都是下面一层的子集。

(3)跳跃式搜索:跳表内的所有链表的元素都是排序的。从顶级链表开始查找,如果查找元素大于当前链表中的取值,就会转入下一层链表继续找。

如下图:查找18原来需要遍历18次,现在只需要7次
在这里插入图片描述
(4)利用空间换时间

(5)与map不同:跳表内所有的元素都是排序的。

XX、高并发

21.高并发解决方案

1.1 应用程序和静态资源文件分离

同 #### 1.2 页面静态化技术

1.2 页面缓存

可以使用Ngnix提供缓存功能、或者页面缓存服务器Squid

1.3 集群与分布式
1.4 反向代理
1.5 CDN

CDN内容分发网络,是集群页面缓存服务器,尽早返回用户需要的数据,加速用户访问速度,也减轻后端服务器的负载压力;


上一篇跳转—Java之并发编程(二)


本篇文章主要参考链接如下:

参考链接1-King说Java

参考链接2-JavaGuide


持续更新中…

随心所往,看见未来。Follow your heart,see light!

欢迎点赞、关注、留言,一起学习、交流!

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

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

相关文章

文献阅读-Deep multi-view learning methods: A review

文献阅读-Deep multi-view learning methods: A reviewAbstract1-Introduction1.1 Comparison with Previous Reviews2 Multi-view Learning Methods in The Deep Learning Scope2.1 Multi-view convolutional neural network2.2. Multi-view auto-encoder2.3. Multi-view gene…

杉数求解器

目录前言一、简介以及安装二、COPT交互式命令行工具2-1、普通工具命令2-2、COPT工具命令三、使用示例3-1、交互模式3-2、Windows下终端窗口直接加载四、Python接口4-1、安装4-2、案例分析五、COPT调优工具5-1、介绍5-2、调优工具相关参数六、Python API参考6-1、COPT常数类总结…

【Jetson安装Nomachine】

0. 介绍 Nomachine是一款免费的远程桌面访问应用程序。支持用户从任何地方访问连接到Internet的计算机。该应用程序允许多个用户访问单个PC&#xff0c;且支持使用不同的操作系统。 官网链接&#xff1a;NoMachine - Free Remote Desktop for Everybody 1. 下载Nomachine 软…

【C++】简单理解内联函数

内联函数1.内联函数的概念2.C为什么要有内联函数&#xff1f;3.内联函数展示3.1查看方式3.2 观察汇编代码4.使用内联函数的注意事项5.内联函数缺点和优点1.内联函数的概念 以inline修饰的函数叫做内联函数&#xff0c;编译时C编译器会在调用内联函数的地方展开&#xff0c;没有…

九龙证券|沪指收获2010年以来最强1月 北向资金净买入额刷新历史纪录

昨日&#xff0c;A股小幅调整&#xff0c;2023年1月行情随之收官。全体来看&#xff0c;1月A股商场拾级而上&#xff0c;盘面出现普涨格局&#xff0c;价值与生长风格均有亮眼体现。三大股指中&#xff0c;上证指数1月上涨5.39%&#xff0c;创2010年以来最佳局面。深证成指、创…

zookeeper 源码分享二 ----启动加载数据

单机zookeeper 启动加载数据 读取磁盘中快照文件&#xff0c;选择其中第一个能正确加载的文件&#xff0c;最多加载100个快照文件。反序列化快照文件&#xff0c;进行内存DataTree数据加载根据最新事物日志&#xff0c;加载事物日志快照并进行反序列化重新执行事物日志中的操作…

OAuth2流程演示示例

目录一、OAuth2流程演示示例1、创建项目结构①客户②认证服务器③资源拥有者④资源服务器2、流程①资源所有者②客户③客户④认证服务器⑤客户⑥资源服务器一、OAuth2流程演示示例 client 客户 authorization-server 认证服务 resource-owner 资源所有者 resource-server 资源服…

anaconda下载安装,镜像源配置修改及虚拟环境的创建

anaconda安装Anaconda 简介Anaconda 安装1.安装流程2.anaconda 配置修改3. 创建虚拟环境4.常用命令Anaconda 简介 Anaconda&#xff08;官方网站&#xff09;就是可以便捷获取包且对包能够进行管理&#xff0c;同时对环境可以统一管理的发行版本。Anaconda包含了conda、Python…

Cocos Creator游戏项目环境搭建和启动

背景获得了一套cocos creator2.4.2编写的游戏源码&#xff0c;需要在本地启动&#xff0c;查看一下是否符合预期要求。所以需要在本地搭建Cocos Creator环境&#xff0c;因为以前没有接触过&#xff0c;经过一番搜索&#xff0c;终于将环境搭建完成&#xff0c;为了备忘&#x…

【Sciter】Sciter 结合 Preact 封装 图片查看器总结

使用 react 结合 sciter 封装 图片查看器 组件 # 效果图 1、图片:宽度大于高度 2、图片:宽度小于高度 # 如何使用 <div class="container"></div

录音软件哪个好?分享两款免费实用的录音软件

有时候我们需要一款录音软件&#xff0c;来录制电脑内部的声音或者电脑外部的声音。比如录制网上无法下载的音乐、录制自己唱歌的声音、录制音频会议等等。那有没有既实用并且试用版就能录音软件呢&#xff1f;当然有&#xff01;小编今天就给大家介绍两款高性价比的录音软件&a…

Nhanes临床数据库挖掘教程2—非正态数据的基线表绘制(2)

美国国家健康与营养调查&#xff08; NHANES, National Health and Nutrition Examination Survey&#xff09;是一项基于人群的横断面调查&#xff0c;旨在收集有关美国家庭人口健康和营养的信息。 地址为&#xff1a;https://wwwn.cdc.gov/nchs/nhanes/Default.aspx 既往我们…

VUE + .NET CORE (.net6)基于asp.net 智能仓储快递物流系统源码

一、源码描述 这是一款简洁十分美观的ASP.NETsqlserver源码&#xff0c;前端vue,框架.netcore,mvc三层架构界面十分美观&#xff0c;功能也比较全面 二、功能介绍 该源码功能十分的全面&#xff0c;具体介绍如下&#xff1a; 用户待取包裹信息可以由快递网点员直接在选择用户…

学习记录 2023/02/01

一、学习内容&#xff1a; 1、OSEK网络管理规范基础&#xff08;CAN_NM报文格式、节点跳过判断机制、网络管理策&#xff09;; 2、UDS诊断服务回顾&#xff08;功能寻址与PHY&#xff0c;CAN升级工具的使用&#xff09;&#xff1b; 二、回顾提升 1、CAN程序升级工具使用(适用…

Linux内核panic核心执行逻辑

什么是OOPSOops是美国人比较常有的口语。就是有点意外&#xff0c;吃惊&#xff0c;或突然的意思。“oops”并不是很严重.对于linux内核来说&#xff0c;Oops就意外着内核出了异常&#xff0c;此时会将产生异常时出错原因&#xff0c;CPU的状态&#xff0c;出错的指令地址、数据…

实训六:启动过程和运行级别

实训六&#xff1a;启动过程和运行级别 2017 年 4 月 16 日 今日公布 实训目标 完成本次实训&#xff0c;将能够&#xff1a; 运用Shell命令管理进程。 在图形界面下管理进程。 配置cron调度。 实训准备 一台安装RHEL6系统的计算机&#xff0c;该系统除了root账户外&…

一文读懂:下一代微服务技术Service Mesh

相信提到微服务大家一定不会陌生&#xff0c;但是说起服务网格&#xff0c;即Service Mesh&#xff0c;很多同学可能就会画大大的问号了&#xff01;话不多说先给结论&#xff1a;我们可以简单的把Service Mesh理解为网络代理&#xff0c;它可以解决传统微服务中的痛点&#xf…

进程状态与优先级

目录 进程状态&#xff1a; tracing stop&#xff1a;追踪暂停状态 Z&#xff1a;僵尸状态&#xff1a; 为什么要有僵尸进程呢&#xff1f; 孤儿进程 进程优先级&#xff1a; 其他概念&#xff1a; 进程切换&#xff1a; pc/eip 环境变量&#xff1a; PATH&#xff1a;全…

nestjs初始化项目

安装nestjs脚手架 npm i -g nestjs/cli初始化项目 nest new <project-name>说明初始化项目成功 结构说明 node_modules:项目所有的依赖src: 项目的主题test: 项目测试目录.eslintrc.js: eslint约束.gitignore: git上传忽略文件nest-cli.json: nest项目配置文件package…

《C++程序设计原理与实践》笔记 第12章 一个显示模型

本章介绍了一个显示模型(display model)&#xff08;GUI的输出部分&#xff09;&#xff0c;并给出了使用示例和基本概念&#xff0c;例如屏幕坐标、线和颜色等。 12.1 为什么需要图形&#xff1f; 我们为什么用四章的篇幅介绍图形以及一章介绍GUI&#xff1f; 图形很有用。…