JAVA多线程进阶篇 13、JUC并发容器

java多线程——juc总结 1.主要内容1. Java JUC 简介2. volatile 关键字-内存可见性3. 原子变量-CAS算法4. ConcurrentHashMap 锁分段机制5. CountDownLatch 闭锁6. 实现 Callable 接口7. Lock 同步锁8. Condition 控制线程通信9. 线程按序交替10. ReadWriteLock 读写锁11. 线程八锁12. 线程池13. 线程调度... 阅读详情

在Java的集合容器框架中,主要有四大类别:List、Set、Queue、Map。

List、Set、Queue接口分别继承了Collection接口,分别代表数组、集合和队列这三大类容器。Map本身是一个接口。

但是,由于缺少安全机制,像ArrayList、LinkedList、HashMap这些容器都是非线程安全的。

1. 同步容器

java语言为此设计了同步容器。内置了Vector、Stack、HashTable等同步容器。同步容器中的方法采用了synchronized进行了同步。

也可以使用Collections工具类将不安全的容器封装了同步容器。

        List<String> list = new ArrayList<>();
        Set<String> set = new HashSet<>();
        Map<String,String> map = new HashMap();

        List<String> list1 = Collections.synchronizedList(list);
        Set<String> set1 = Collections.synchronizedSet(set);
        Map<String,String> map1 = Collections.synchronizedMap(map);

1.1 同步容器存在性能问题

同步容器中的大量的方法采用了synchronized进行了同步,在并发环境中都会争抢这一把锁,同时只能有一个线程对容器进行访问,这必然会影响到执行性能。

1.2 同步容器依旧存在安全问题

public class ListConcurrentTest2 {

    static Vector<Integer> vector = new Vector<Integer>();

    public static void main(String[] args) {

        for (int i = 0; i < 1000; i++) {
            vector.add(1);
        }

        Thread thread1 = new Thread() {
            public void run() {
                for (int i = 0; i < vector.size(); i++)
                    vector.remove(-1);
            }
        };

        Thread thread2 = new Thread() {
            public void run() {
                for (int i = 0; i < vector.size(); i++)
                    vector.get(i);
            }
        };
        thread1.start();
        thread2.start();
    }
}

运行结果,由于线程删除了vector的元素,导致thread2 遍历时,下标元素被删除不存在,发生越界错误。

Exception in thread "Thread-0" java.lang.ArrayIndexOutOfBoundsException: -1
	at java.util.Vector.elementData(Vector.java:737)
	at java.util.Vector.remove(Vector.java:835)
	at com.concurrent.juc.ch13.ListConcurrentTest2$1.run(ListConcurrentTest2.java:26)

Process finished with exit code 0

1.3 ConcurrentModificationException

在对Vector等容器并发地进行迭代修改时,会报ConcurrentModificationException异常,但是在并发容器中不会出现这个问题。 比如:

public class ListConcurrentTest3 {
    public static void main(String[] args)  {
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(1);
        list.add(2);
        list.add(3);

        Iterator<Integer> iterator = list.iterator();
        while(iterator.hasNext()){
            Integer integer = iterator.next();
            list.remove(integer);
        }
    }
}

此时,由于iterator在迭代时修改了list内容,报错

Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
	at java.util.ArrayList$Itr.next(ArrayList.java:859)
	at com.concurrent.juc.ch13.ListConcurrentTest3.main(ListConcurrentTest3.java:22)

2. 并发容器

同步容器将所有对容器状态的访问都串行化了,以保证了线程的安全性,但是安全隐患仍然存在,而且严重降低了并发性,当多个线程竞争容器时,性能急剧下降。
因此Java5.0开始针对多线程并发访问设计,提供了并发性能较好的并发容器,有以下优点。

  • 根据具体场景进行设计,尽量避免synchronized,提供并发性。
  • 定义了一些并发安全的复合操作,并且保证并发环境下的迭代操作不会出错。

2.1 ConcurrentHashMap

ConcurrentHashMap可以做到读取数据不加锁,对数据分桶,在内部采用了一个叫做Segment数组,Segment元素指向一个Map。ConcurrentHashMap需要两次Hash操作,第一次Hash定位到Segment,第二次Hash定位到元素所在的链表的头部,因此,这一种结构的带来的副作用是Hash的过程要比普通的HashMap要长,但是带来的好处是写操作的时候可以只对元素所在的Segment进行加锁即可,不会影响到其他的Segment。
ConcurrentHashMap的源码值得深入研究,可以参考《JAVA多线程源码篇》

2.2 CopyOnWriteArrayList

Copy-On-Write是一种用于程序设计中的优化策略。其基本思路是,在读时共享数据,但是当有线程要修改元素时会将内部数组拷贝一份,对拷贝数组进行修改,拷贝完成后再更正链接指向。JUC容器里有CopyOnWriteArrayList和CopyOnWriteArraySet,可以在非常多的并发场景中使用到。

2.3 BlockingQueue

BlockingQueue常用于生产者消费者场景。队列满时,生产者会阻塞,队列空时,消费者会阻塞。可以方便地实现线程协同工作。

  • 插入方法
    • add(o) 如果无法立即执行,抛出异常。
    • offer(o) 返回boolean,表示是否成功操作。
    • offer(o, timeout, timeunit) 带超时参数的阻塞方法。
    • put(o) 阻塞方法,如果队列满将阻塞。
  • 删除方法
    • remove(o) 如果无法立即执行,抛出异常。
    • poll(o) 返回boolean,表示是否成功操作。
    • poll(o, timeout, timeunit) 带超时参数的阻塞方法。
    • take(o) 阻塞方法,如果队列空将阻塞。

2.3.1 ArrayBlockingQueue

ArrayBlockingQueue 是一个有界的阻塞队列,其内部实现是将对象放到一个数组里。有界也就意味着,它不能够存储无限多数量的元素。它有一个同一时间能够存储元素数量的上限。

2.3.2 LinkedBlockingQueue

LinkedBlockingQueue 内部以一个链式结构(链接节点)对其元素进行存储。如果需要的话,这一链式结构可以选择一个上限。如果没有定义上限,将使用 Integer.MAX_VALUE 作为上限。

2.3.3 PriorityBlockingQueue

PriorityBlockingQueue 是一个无界的并发队列。它使用了和类 java.util.PriorityQueue 一样的排序规则。你无法向这个队列中插入 null 值。所有插入到 PriorityBlockingQueue 的元素必须实现 java.lang.Comparable 接口。

2.3.4 SynchronousQueue

SynchronousQueue 是一个特殊的队列,它的内部同时只能够容纳单个元素。如果该队列已有一元素的话,试图向队列中插入一个新元素的线程将会阻塞,直到另一个线程将该元素从队列中抽走。

2.3.5 DelayQueue

DelayQueue 对元素进行持有直到一个特定的延迟到期。在每个元素的 getDelay() 方法返回的值的时间段之后才释放掉该元素。如果返回的是 0 或者负值,延迟将被认为过期,该元素将会在 DelayQueue 的下一次 take 被调用的时候被释放掉。

总结

Java5.0提供了并发性能较好的并发容器,根据具体场景进行设计,尽量避免synchronized,提供并发性。 定义了一些并发安全的复合操作,并且保证并发环境下的迭代操作不会出错。

多线程系列在github上有一个开源项目,主要是本系列博客的实验代码。

https://github.com/forestnlp/concurrentlab

如果您对软件开发、机器学习、深度学习有兴趣请关注本博客,将持续推出Java、软件架构、深度学习相关专栏。

您的支持是对我最大的鼓励。

黑马并发编程JUC总结 并发编程总结1并发编程2.进程和线程2.1定义2.2并发和并行2.3应用异步调用并发应用3.java线程3.1线程创建创建线程方法1创建方法2Thread和Runable的区别创建方法33.2线程运行3.3线程运行线程的栈线程上下文切换常见方法startrunsleepinterruptyieldsetPriorityjoininterrupt两阶段终止模式LockSupport3.4主线程和守护线程3.5线程5种状态3.6线程的六种状态3.7烧水泡茶案例join思路4.并发之共享模型4.1多线程带来的共享 阅读详情

相关推荐

java juc包介绍

目录 1.Java JUC 简介 2.volatile 关键字-内存可见性 3.原子变量-CAS算法 4.ConcurrentHashMap 锁分段机制 5.CountDownLatch 闭锁 6.实现Callable 接口 7.Lock 同步锁 8.Condition 控制线程通信 9.线程按序交替 10.ReadWriteLock 读写锁 11.线程八锁 12.线程池 13.线程调度 14.F...

ganyongming的博客 1137

JUC框架-并发容器源码详解

ConcurrentSkipListMap是一个有序的映射表,其中每个键都映射到一个值。它使用跳表数据结构来实现,跳表是一种通过维护多个有序链表来提供快速查找、插入和删除操作的数据结构。ConcurrentSkipListMap的设计目标是提供接近于O(1)的平均时间复杂度,对于常见的操作如get、put、remove等。

A的博客 1560

并发编程JUC(多线程)面试篇

并发编程相关面试题

kingandsong的博客 1795

线程系列 7 - JUC高并发容器类

JUC高并发容器是基于非阻塞算法(或者无锁编程算法)实现的容器类,无锁编程算法主要通过 CAS(保障操作的原子性) + Volatile(保障变量内存的可见性)组合实现。① 开销较小:不需要在内核态和用户态之间切换进程。② 读写不互斥:只有写操作需要使用基于CAS机制的乐观锁,读读操作之间可以不用互斥。JUC包中提供了List、Set、Queue、Map各种类型的高并发容器。ListJUC包中的高并发List主要有CopyOnWriteArrayList,对应的基础容器为ArrayList。

STRANGE-P 的博客 667

【Java面试题汇总】多线程、JUC、锁篇(2026版)

线程和进程的区别、CAS的ABA问题、AQS、哪些地方使用了CAS、怎么保证线程安全、线程同步方式、synchronized的用法及原理、Lock、volatile、线程的六个状态、ThreadLocal、线程通信方式、创建方式、两种创建线程池的方法、线程池设置合适的线程数、线程安全的集合?ConcurrentHashMap、JUC

种一棵树最好的时间是十年前,其次是现在 1万+

S32K344 Flash Driver实战:手把手教你实现任意字节写入与扇区解锁(含C40_Ip避坑指南)

本文深入解析S32K344微控制器的Flash驱动开发,重点解决C40_Ip驱动库的8字节对齐限制和扇区保护锁问题。通过实战案例和代码示例,详细介绍了如何实现任意字节写入、扇区解锁及性能优化策略,为Bootloader和OTA升级等应用提供可靠解决方案。

weixin_33713707的博客 432

JUC容器介绍

文章目录JUC结构1、tools(工具类)CountDownLatchCyclicBarrierSemaphoreCyclicBarrier 和 CountDownLatch 区别2、executorJava创建线程池的方式线程池的理解以及使用3、atomic4、Lock锁(重点)什么是Synchronized?Synchronized和lock5、集合类不安全 JUC结构 tools(工具类):又叫信号量三组工具类,包含有 CountDownLatch(倒计数) 是一个同步辅助类,在完成一组正在其

致力于不留技术债务cuizb.top 526

车辆横向控制MPC实战:从‘老王模型’到CasADi求解的保姆级避坑指南

本文详细解析了车辆横向控制MPC的实战应用,从经典动力学模型选择到CasADi求解器的优化配置,提供了一套完整的避坑指南。重点介绍了车辆动力学模型的验证要点、CasADi环境的高效配置技巧以及MPC问题建模的核心要素,帮助开发者快速实现稳健的横向控制方案。

weixin_42524499的博客 346

Juc并发编程11——深入源码:常用并发容器、阻塞队列使用与原理

前言 本文将介绍常用的并发容器,比较传统容器与并发容器的区别,介绍并发容器的基本原理。是面试常考、工作常用的热门知识点。

半旧518的博客 950

探索热阻测试仪在半导体器件热管理中的应用与前景

T3Ster是MicReD研发的热测试仪,运用JEDEC稳态实时测试方法,专业测试分离或集成的双极型晶体管、MOS晶体管、常见的三极管、LED封装和半导体闸流管等器件的热特性。利用瞬态温升技术,可测得器件稳态热阻和温升,不但可以测得半导体器件稳态热阻和温升,而且可以直接测量各部分对于温升的贡献,计算芯片热流路径上的纵向热阻构成,对器件热可靠性设计、散热问题解决、产品性能提升和长期可靠性至关重要。关键词:T3ster,Micred,功率循环,结温测试,热阻测试,结温热阻测试,半导体热特性测试;

anscos_Olivia的博客 896

Grafana企业版vs开源版:从安装到插件管理的完整对比实测(含离线部署技巧)

本文深入对比Grafana企业版与开源版在安装流程、插件管理和功能限制等方面的差异,特别针对离线部署场景提供实用技巧。通过实测数据源支持、权限管理等核心功能,帮助企业用户做出明智选择,同时详细介绍离线安装和插件签名验证等关键操作。

weixin_29313817的博客 104

JUC之各种线程安全容器

CopyOnWrite系列、Concurrent系列大体结构Concurrent系列CopyOnWrite系列 大体结构 总体结构比较简单。 Concurrent系列 如果应用侧重于Map放入与获取的速度,而不在意顺序的话ConcurrentHashMap很好,反之ConcurrentSkipListMap 更适合,如果我们对大量数据做频繁的修改,ConcurrentSkipListMap 也可...

weixin_42610002的博客 694

YOLOv11改进策略【Conv和Transformer】| IJCAI 2024 利用FreqFormer中的SFA 空间 - 频率注意力和CTA 通道转置注意力 二次改进C3k2

在FreqFormer模型中,SFA(Spatial-Frequency Attention)和CTA(Channel Transposed Attention)模块是关键组成部分,它们针对传统Transformer在图像超分辨率任务中的不足而设计,旨在更好地恢复高频细节,提升模型性能。

Limiiiing的博客 758

Java多线程之JUC

JUC 文章目录JUC1、什么是JUC?1.1、进程和线程1.2、并发&并行1.3、wait和sleep的区别2、锁(*重点)2.1、synchronized和Lock的区别2.2、生产者&消费者问题2.3、那么锁是什么?如何判断锁的是谁?(8锁现象)3、集合类不安全4、Callable接口5、常用的辅助类(必会)5.1、CountDownLatch(减法计数器)5.2、CyclicBarrier(加法计数器)5.3、semaphore(信号量)6、读写锁(共享锁,排他锁)7、阻塞队列7.1

小小周的博客 1997

Android 12.0 kenel中修改rom系统内部存储的大小

在12.0的系统rom产品开发定制中,在对一些产品开发中的配置需求方面,由于在产品后续订单中,有些产品是出口的,但是硬件方面已经定板,时间比较仓促,所以 就需要软件方面在rom内部存储的大小方面作假,修改rom真实的大小容量,所以就需要在kenel驱动部分来修改这部分的值最好了,接下来分析下计算rom容量的 相关代码,然后做出相关的修改,来实现功能

安卓兼职framework和app工程师的博客 1678

Arcgis模型构建器01——写一个简单的模型

在使用模型构建器解决这个需求之前,我们要想清楚如果我们手动解决的话,应该如何去处理,因为构建模型的过程正是基于我们手动处理的过程来构建的。我有一个全国的dem影像数据和一个陕西省边界范围矢量,现在我想获取陕西省的dem影像的坡度数据。填写完之后点击确定,我们发现,两个输入数据和工具连接起来了,并且通过裁剪工具得到一个中间结果,即。我们发现工具框和中间数据框都存在阴影,说明已经运行过了这个模型,不报错就说明模型运行成功!现在我们就把数据和工具都串联起来了,成功构建好了模型。

爱吃雪糕的小布丁的博客 918

Java多线程和JUC

多线程和JUC

m0_51380540的博客 385

在 SAP BTP ABAP 环境中测试多租户 SaaS 解决方案的完整实践指南

ABAP SaaS测试阶段关键实践 在SAP BTP ABAP环境中开发多租户SaaS解决方案时,测试阶段(TST)对确保产品质量尤为关键。测试阶段应包含两个主要维度: 业务功能验证: 通过软件组件管理确保测试环境与代码仓库同步 创建并验证业务角色分配,确保权限配置正确 测试Fiori Launchpad导航流程和跨应用跳转 验证inbound/outbound通信配置 自动化质量管控: 在开发环境(DEV)执行本地ATC检查和单元测试 通过ABAP Test Cockpit(ATC)进行代码质量检查 集成

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 298

JUC(Lock锁、线程间通信、并发容器类、JUC强大的辅助类、Callable接口、CompletableFuture、阻塞队列、ThreadPool线程池、多线程高并发底层原理)

文章目录1. JUC概述及回顾1.1. JUC是什么?1.2. 进程和线程1.3. 并行和并发1.4. wait/sleep的区别1.5. 创建线程回顾1.6. lambda表达式1.6.1. 什么是lambda1.6.2. 案例1.6.3. 函数式接口1.6.4. 小结1.7. synchronized回顾1.8. synchronized的8锁问题2. Lock锁2.1. ReentrantLock可重入锁(递归锁)2.1.1. 测试可重入性2.1.2. 测试公平锁2.1.3. 限时等待2.1.4. R

小丁的博客 584

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Java多线程与并发编程

Java多线程与并发编程

weixin_45427945的博客 879

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

一篇神文就把java多线程,锁,JMM,JUC和高并发设计模式讲明白了

说句实话,如果一个打工人不想提升自己,那便没有工作的意义,毕竟大家也没有到养老的年龄。当你的技术在一步步贴近阿里p7水平的时候,毫无疑问你的薪资肯定会涨,同时你能学到更多更深的技术,交结到更厉害的大牛。推荐一份Java架构之路必备的学习笔记,内容相当全面!!!成年人的世界没有容易二字,前段时间刷抖音看到一个程序员连着加班两星期到半夜2点的视频。在这个行业若想要拿高薪除了提高硬实力别无他法。你知道吗?现在有的应届生实习薪资都已经赶超开发5年的程序员了,实习薪资26K,30K,你没有紧迫感吗?

a1901149的博客 506

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

JUC类和接口的分类与简介

摘要:Java并发工具包(JUC)提供了丰富的并发编程工具,主要包括三大部分:1.锁机制:包括ReentrantLock(可重入锁)、ReentrantReadWriteLock(读写锁)和StampedLock(支持乐观读的升级版读写锁),分别支持不同的并发场景。2.并发工具类:涵盖线程池(Executor框架)、并发容器(如ConcurrentHashMap)、原子变量(Atomic类)、同步器(CountDownLatch等)以及Fork/Join框架等。3.其他功能:包括线程本地变量、随机数生成、异

晨港飞燕的专栏 1382

视频教程-Java系列技术之多线程与JUC-Java

Java系列技术之多线程与JUC 钟洪发,于2008年7月毕业于西南交通大学...

weixin_33688101的博客 413

JUC 并发编程

JUC 并发编程 1、什么是JUC java.util 工具包、包、分类 2、线程和进程 线程和进程,如果不能使用一句话说出来的技术,就是不扎实! 进程:一个程序,QQ.exe 一个进程往往包含多个多个线程 java默认有几个线程? 2个 main线程,GC线程 线程:程序执行的最小单元 java真的能开启线程吗? 开不了 只能通过调用本地方法,java无法直接操作硬件 并发、并行 并发编程:并发、并行 并发(多线程操作同一资源) 并行(多个人一起行走),多个线程可以同时执行 线程池 并

yao_wen_yu的博客 803

Juc 概述

一共13 个章节,每天坚持一个章节。 1、什么是 JUC 2、Lock 接口 3、线程间通信 4、线程间定制化通信 5、集合的线程安全 6、多线程锁 7、Callable 接口 8、JUC 三大辅助类: CountDownLatch CyclicBarrier Semaphore 9、读写锁: ReentrantReadWriteLock 10、BlockingQueue阻塞队列 11、ThreadPool 线程池 12、Fork/Join 分支合并框架 13、CompletableFuture异步回调 文

weixin_45417821的博客 646
上一篇: JAVA多线程进阶篇 12、JUC线程池之ForkJoinPool
下一篇: JAVA多线程番外篇 2、while和wait的配合使用
悟空学编程
博客等级 码龄12年 32粉丝 123原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟空学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值