有关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很好地解决了这个问题。它会让服务线程在队列为空时

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

相关推荐
_GR14 分钟前
每日OJ题_牛客_牛牛冲钻五_模拟_C++_Java
java·数据结构·c++·算法·动态规划
无限大.30 分钟前
c语言实例
c语言·数据结构·算法
@haihi42 分钟前
冒泡排序,插入排序,快速排序,选择排序
数据结构·算法·排序算法
丢掉幻想准备斗争1 小时前
数据结构(栈和队列的实现)
数据结构
zengy52 小时前
Effective C++中文版学习记录(三)
数据结构·c++·学习·stl
&梧桐树夏5 小时前
【算法系列-链表】删除链表的倒数第N个结点
数据结构·算法·链表
QuantumStack5 小时前
【C++ 真题】B2037 奇偶数判断
数据结构·c++·算法
wclass-zhengge6 小时前
数据结构篇(绪论)
java·数据结构·算法
Dylanioucn6 小时前
【分布式微服务云原生】探索Redis:数据结构的艺术与科学
数据结构·redis·分布式·缓存·中间件
何事驚慌6 小时前
2024/10/5 数据结构打卡
java·数据结构·算法