有关List的线程安全、高效读取:不变模式下的CopyOnWriteArrayList类、数据共享通道:BlockingQueue

有关List的线程安全

队列、链表之类的数据结构也是极常用的,几乎所有的应用程序都会与之相关。在java中,

ArrayList和Vector都使用数组作为其内部实现。两者最大的不同在与Vector是线程安全的。

而ArrayList不是。此外LinkedList使用链表的数据结构实现了List。但是LinkedList并

不是线程安全的。参考对HashMap的包装,这里我们也可用用Collections.synchronizedList

方法来包装任意List:

public static List<String> l = Collections.synchronizedList(new LinkedList<String>());

此时生成的List对象就是线程安全的了。

ConcurrentLinkedQueue来实现高并非的队列。应该算是高并发环境中性能最好的队列。

它之所以很好性能,是因为其内部复杂的实现。这个方法没有任何锁操作。

线程安全完全由CAS操作和队列的算法来保证。整个方法的核心是for循环。

这个循环没有出口,直到尝试成功。这也符合CAS操作的流程。

高效读取:不变模式下的CopyOnWriteArrayList类

在很多应用场景中,读操作可能会远远大于写操作。

比如,有些系统级别的信息,往往只需要加载或者修改很少的次数,但是

会被系统内所有模块频繁访问。

由于读操作根本不会修改原有的数据,因此对于每次读取都进行加锁其实是一种

资源浪费。JDK中提供了CopyOnWriteArrayList类,对它来说,读取是完全不用

加锁的,并且更好的消息是,写入也不会阻塞读取操作。只有写入和写入之间需要

进行同步等待。

数据共享通道:BlockingQueue

前面提到了ConcurrentLinkedQueue类是高性能的队列。对于并发程序而言,

高性能自然是一个我们需要追求的目标,但多线程开发模式还会引入一个问题,

那就是如何进行多个线程间的数据共享呢?比如,线程A希望给线程B发一条消息

用什么方式告知线程B是比较合理的呢?

一般来说,我们总希望整个系统是松散耦合的。

比如,你所在小区的物业希望可用得到一些业主的意见,设立一个

意见箱,如果对物业有任何要求或意见都可用投到意见箱里。

如果对物业有任务要求或者意见都可用投到意见箱里。

作为业主的你并不需要直接找到物业相关的工作人员

就能表达意见。实际上,物业的工作人员也可能经常发生变动。

直接找工作人员未必是一件方便的事情。而你投递到意见箱的意见总是

会被物业的工作人员看到,不管是否发生了人员的变动。

这样你就可用很容易地表达自己的诉求了。

你既不需要直接和他们对话,又可用轻松提出自己的建议。

将这个模式映射到我们程序中,就是说我们既希望线程A能够通知线程B,

又希望线程A不知道线程B的存在。这样,如果将来进行重构或者升级,

我们完全可用不修改线程A,而直接把线程B升级为线程B,

保证系统的平滑过度。而这中间的意见箱就可用使用BlockingQueue来实现。

与之前提到的ConcurrentLinkedQueue类或者CopyOnWriteArrayList类不同,

BlockingQueue是一个接口,并非一个具体的实现。

ArrayBlockingQueue类和LinkedBlockingQueue类。

ArrayBlockingQueue更适合做有界队列,

LinkedBlockingQueue适合做无界队列。

BlockingQueue之所以适合作为数据共享的通道,其关键在于

Blocking上,Blocking是阻塞的意思,但服务线程(服务线程指

不断获取队列中的消息,进行处理的线程)处理完成队列中所有的消息后,

它如何知道下一条消息何时到来呢?

一种简单的做法是让这个线程按照一定的时间间隔不停地循环和监控这个队列。

这是一种可行的方案,但显然造成了不必要的资源浪费。

而且循环周期也难以确定。

BlockingQueue很好地解决了这个问题。它会让服务线程在队列为空时

进行等待,当有新的消息进入队列后,自动将线程唤醒。

相关推荐
刘马想放假2 天前
Modbus 全栈技术解析:TCP、RTU、ASCII、RTU over TCP
数据结构·网络协议
北域码匠3 天前
冒泡排序太慢?鸡尾酒排序双向优化,原生 C# 零第三方库完整代码
数据结构·排序算法·泛型·c# 算法·鸡尾酒排序·原生 c# 开发·冒泡排序优化·嵌入式算法
Darling噜啦啦10 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
小小工匠11 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
玖玥拾11 天前
C/C++ 数据结构(七)栈、容器适配器
c语言·数据结构·c++··容器适配器
Qres82111 天前
算法复键——树状数组
数据结构·算法
牛油果子哥q11 天前
并查集(DSU)超精讲,路径压缩、按秩合并、万能模板、连通性判定、最小生成树与刷题实战全解
数据结构·c++·最小生成树·并查集
凌波粒11 天前
LeetCode--491.递增子序列(回溯算法)
数据结构·算法·leetcode
世人万千丶11 天前
成语接龙小应用 - HarmonyOS ArkUI 开发实战-TextInput与List列表-PC版本
华为·list·harmonyos·鸿蒙·鸿蒙系统
WL学习笔记11 天前
单项不带头不循环链表
数据结构·链表