Java 并发基础知识 CopyOnWriteArrayList 已完全解析

小夏 科技 更新 2024-02-19

优质作者名单

j**a 并发基础知识:CopyOnWriteArrayList 完全解析 - Programmer Goodcopyonwritearraylist该类最大的优点是读取时不需要锁定,非常适合读写较多的并发场景,因为它的写入操作是通过复制底层数据来实现的,从而保证了读取数据的一致性和效率,此外,它简单易用, 是快速实现线程安全列表的不错选择,CopyOnWriteArrayList 在以读取操作为主的场景下可以提供出色的性能和稳定性。

copyonwritearraylist类实现listrandomaccesscloneableinterface 是一个线程安全变体,在修改诸如addset等等),它复制底层数组,然后修改复制的数组,修改完成后再将内部引用指向新的数组,这使得读取操作可以在没有任何锁定的情况下进行,因此非常适合读取次数多、写入次数少的并发场景。

假设有一个新闻发布系统,它维护着一个需要经常阅读的新闻列表(用户浏览新闻),但只是偶尔修改(发布新新闻或更新现有新闻),在本例中,使用copyonwritearraylist存储新闻列表可能是一个不错的选择。

读取操作:当用户浏览新闻时,系统需要从新闻列表中读取数据,因为copyonwritearraylist读取操作是无锁的,因此多个用户可以同时阅读新闻列表而不会相互阻塞,这有助于提高系统的吞吐量。 写入操作:当新闻编辑发布新新闻或更新现有新闻时,系统需要修改新闻列表copyonwritearraylist写入会复制整个底层阵列,但由于它们不常见,因此不会成为性能瓶颈,并且由于写入是在新阵列上进行的,因此读取不会被阻止,这有助于保持系统响应。 copyonwritearraylist类特别适合读取和写入次数较低的方案,它们通常用于解决如下方案中的问题:

线程安全:在多线程环境中,正常arraylist如果有多个线程同时修改,则不是线程安全的arraylist,这可能导致数据不一致copyonwritearraylist线程安全是通过内部复制机制来保证的,即当一个线程修改列表(如添加或删除元素)时,会先复制当前列表的副本,然后对副本进行修改,修改完成后再将内部引用指向新副本,这样读取操作就可以继续在原始列表上进行,而不会被修改所阻塞操作。读/写分离:由于copyonwritearraylist写入操作(修改操作)在新阵列上执行,而读取操作在原始未修改的阵列上执行,因此读取和写入操作不会相互干扰copyonwritearraylist它在高并发读取的场景中表现良好。 数据一致性:通过复制整个底层数组来确保修改操作的原子性copyonwritearraylist提供了强一致性保证,因此读取者要么看到修改前的列表状态,要么看到修改后的列表状态,而不是中间状态。 copyonwritearraylist它并不适合所有场景,因为写入操作需要复制整个底层数组,因此当列表较大或写入操作非常频繁时,会导致内存开销大,性能下降。

下面是一个简单的 j**a 程序,演示了如何使用它copyonwritearraylist类,一个是在案例中创建的copyonwritearraylist实例,并模拟多个线程同时读写,如下所示:

import j**a.util.list; 

import j**a.util.concurrent.copyonwritearraylist;

public class copyonwritearraylistdemo catch (interruptedexception e)

system.out.println("writer thread finished!");

.start();

启动多个线程以从列表中读取元素

for (int i = 0; i < 3; i++)catch (interruptedexception e)

.start();

在上面,创建了一个copyonwritearraylist实例list,启动一个线程来模拟一个写入操作来向列表中添加一个元素,这个线程使用循环将 5 个元素添加到列表中,每次添加后暂停 100 毫秒以模拟耗时的操作,然后,启动 3 个线程来模拟读取操作以从列表中读取一个元素, 每个线程使用循环读取列表 10 次,并在每次读取后暂停 50 毫秒以模拟耗时的操作,因为copyonwritearraylist底层数组在新数组上复制和修改,因此读取不受写入的影响,从而确保线程安全和数据一致性。

copyonwritearraylist类提供线程安全arraylist实现,它通过在修改时复制基础数组来实现线程安全,因此它特别适合读取较多而写入较少的并发方案,以下是 CopyOnWriteArrayList 类中一些主要方法的含义:

一、施工方法

copyonwritearraylist():创建一个空的copyonwritearraylistcopyonwritearraylist(collection c):创建一个包含指定集合中所有元素的元素copyonwritearraylist2.阅读方法(通常不会阻止,因为您在阅读时不需要锁定)。

get(int index):获取指定索引位置的元素。 iterator():返回一个迭代器,用于循环访问列表中的元素。 listiterator():返回一个列表迭代器,该迭代器允许在任何方向上遍历列表,并修改元素(尽管在copyonwritearraylist修改一个元素实际上会被抛出unsupportedoperationexceptiontoarray():返回包含列表中所有元素的数组。 3.修改方法(修改时复制基础数组可能需要更多时间)。

add(e e):在列表末尾添加元素。 add(int index, e element):在列表中的指定位置插入元素。 addall(collection c):将指定集合中的所有元素添加到列表的末尾。 addall(int index, collection c):将指定集合中的所有元素插入到列表中的指定位置。 set(int index, e element):替换列表中指定的元素。 remove(int index):从列表中的指定位置删除元素。 remove(object o):删除列表中的第一个指定元素(如果存在)。 removeall(collection c):从列表中删除指定集合中包含的所有元素。 retainall(collection c):仅保留列表中指定集合中包含的元素。 clear():清除列表中的所有元素。 4. 查询方式

contains(object o):检查列表中是否包含指定的元素。 containsall(collection c):检查列表是否包含指定集中的所有元素。 isempty():检查列表是否为空。 size():返回列表中的元素数。 indexof(object o):返回列表中指定元素首次出现的索引,如果列表不包含此元素,则返回 -1。 lastindexof(object o):返回列表中指定元素最后一次出现的索引,如果列表不包含此元素,则返回 -1。 5.其他方法

sublist(int fromindex, int toindex):返回列表中指定的部分视图(注意返回的不是新的独立列表,对返回列表的修改会影响原始列表,而是由于。copyonwritearraylist,则会抛出修改操作unsupportedoperationexceptionequals(object o):比较此列表是否等于指定的对象。 hashcode():返回列表的哈希码值。 copyonwritearraylist写入操作(修改方法)是通过复制底层数组来实现的,因此在高并发写入场景中性能可能会受到严重影响,在这种情况下,其他并发数据结构(如concurrenthashmapsegment数组concurrentlinkedqueueconcurrentskiplistmap等等,可能是更好的选择。 但是,建议在读取次数较多且写入次数较少的情况下使用copyonwritearraylist,它提供了高效且线程安全的解决方案。

j**a 并发基础知识:CopyOnWriteArrayList 完全解析 - Programmer GoodcopyonwritearraylistClass 是一个线程安全列表实现,非常适合读取次数多、写入次数少的并发场景,优点是读取操作不需要锁定,性能高效,可以保证数据的一致性。 在写入操作过程中,会复制底层阵列,避免阻塞读取操作,从而实现读写分离。 但是,写入成本很高,因为每次修改都需要复制整个数组,这在数据量大或写入频繁时会产生显著的性能开销,并且不适合需要频繁修改列表的场景,因为每次修改都会生成一个新的数组副本, 导致更高的内存占用。

在读取操作远多于写入操作,且实时数据要求不高的场景下copyonwritearraylist这是一个不错的选择,但如果写入频繁或数据量大,建议考虑其他更适合的并发数据结构,例如:concurrentlinkedqueueconcurrenthashmap等。

跟着我,每天学习互联网编程技术——程序员古德结束!end!end!

j**a 并发基础知识:ConcurrentSkiplistMap 已完全解析。

j**a 并发基础:ConcurrentSkipListSet 完整分析!

j**a 并发基础知识:SynchronousQueue 完整分析!

j**a 并发基础知识:ConcurrentLinkedQueue 全分辨率!

J**A 并发基础知识:交换器全分辨率!

相似文章

    Java 并发基础知识 CyclicBarrier 分析!

    优质作者名单 J A 并发基础 CyclicBarrier 的综合分析!CyclicBarrier 的优势在于实现了线程之间的相互等待和协作,保证了所有线程只有在到达预定的障碍点后才能继续执行,它支持障碍的复用,非常适合多轮次任务同步,此外,CyclicBarrier 还允许在障碍点执行特定的操作,...

    Java 并发基础知识 CountDownLatch 全面分析!

    优质作者名单 j a 并发基础知识 CountDownLatch 完整分析!程序员古德countdownlatch优点是可以简洁高效地协调多个线程的执行顺序,保证只有一组线程完成后才会触发其他线程的执行,适用于资源加载 任务初始化等场景。它提供了清晰的等待通知机制,易于理解和使用,是提高多线程程序性...

    Java 并发基础知识 LinkedBlockingQueue 完整分析!

    优质作者名单 J A 并发基础知识 LinkedBlockingDeque 完整分析!程序员古德linkedblockingqueue类是具有链表结构的高效线程安全队列,具有出色的并发性能 灵活的阻塞和非阻塞操作,以及与生产者和消费者模式一起工作的能力linkedblockingqueue它还具有高...

    Java 并发基础知识 LinkedBlockingDeque 全面分析!

    优质作者名单 J A 并发基础知识 LinkedBlockingDeque 完整分析!程序员古德linkedblockingdeque它提供了双端队列的线程安全实现,支持队列两端的高效插入和删除操作,并具有可以很好地协调生产者和消费者之间速度差异的阻塞功能,其内部链表结构使得出色的并发性能,非常适合...

    Java 并发基础知识 PriorityBlockingQueue 已完全解决!

    优质作者名单 J A 并发基础知识 PriorityBlockingQueue 已完全解析!程序员古德priorityblockingqueue同时,作为blockingqueue接口的实现,它提供了线程安全队列操作,适用于多线程环境下的任务调度和资源管理,简洁而强大的API使开发者可以轻松处理复杂...