线程安全的list之synchronizedList和CopyOnWriteArrayList
在上篇文章中我们已经介绍了其他的一些list集合,如ArrayList、linkedlist等。不清楚的可以看下上篇文章 https://www.jianshu.com/p/6227ab5b33f7
但是向ArrayList这些会出现线程不安全的问题,我们该怎样解决呢?接下来就是要介绍我们线程安全的list集合synchronizedList和CopyOnWriteArrayList。
synchronizedList的使用方式:
从上面的使用方式中我们可以看出,synchronizedList是将List集合作为参数来创建的synchronizedList集合。
synchronizedList为什么是线程安全的呢?
我们先来看一下他的源码:
我们大概贴了一些常用方法的源码,从上面的源码中我们可以看出,其实synchronizedList线程安全的原因是因为它几乎在每个方法中都使用了synchronized同步锁。
synchronizedList官方文档中给出的使用方式是以下方式:
在以上源码中我们可以看出,官方文档是建议我们在遍历的时候加锁处理的。但是既然内部方法以及加了锁,为什么在遍历的时候还需要加锁呢?我们来看一下它的遍历方法:
从以上源码可以看出,虽然内部方法中大部分都已经加了锁,但是iterator方法却没有加锁处理。那么如果我们在遍历的时候不加锁会导致什么问题呢?
试想我们在遍历的时候,不加锁的情况下,如果此时有其他线程对此集合进行add或者remove操作,那么这个时候就会导致数据丢失或者是脏数据的问题,所以如果我们对数据的要求较高,想要避免这方面问题的话,在遍历的时候也需要加锁进行处理。
但是既然是使用synchronized加锁进行处理的,那肯定避免不了一些锁开销。有没有效率更好的方式呢?那就是我们另一个主要的并发集合CopyOnWriteArrayList。
CopyOnWriteArrayList是在执行修改操作时,copy一份新的数组进行相关的操作,在执行完修改操作后将原来集合指向新的集合来完成修改操作。具体源码如下:
从以上源码我们可以看出,它在执行add方法和remove方法的时候,分别创建了一个当前数组长度+1和-1的数组,将数据copy到新数组中,然后执行修改操作。修改完之后调用setArray方法来指向新的数组。在整个过程中是使用ReentrantLock可重入锁来保证不会有多个线程同时copy一个新的数组,从而造成的混乱。并且使用volatile修饰数组来保证修改后的可见性。读写操作互不影响,所以在整个过程中整个效率是非常高的。
synchronizedList适合对数据要求较高的情况,但是因为读写全都加锁,所有效率较低。
CopyOnWriteArrayList效率较高,适合读多写少的场景,因为在读的时候读的是旧集合,所以它的实时性不高。
linkedlist线程安全吗
linkedlist的线程是不安全的,list的三个子类arraylist、linkedliat和vector,只有vector是线程安全的
arraylist是线程安全的吗
List 接口下有 ArrayList 和Vector ArrayList不是现成安全的,而Vector是现成安全的。 为什么呢?很简单,打开源码看看 同样的实现Vector的方法前加了 synchronized 关键字 那你说为什么? 人家就是这样子写的
为什么java.util.concurrent 包里没有并发的ArrayList实现
很难去开发一个通用并且没有并发瓶颈的线程安全的List。像ConcurrentHashMap这样的类的真正价值(The real point \/ value of classes)并不是它们保证了线程安全。而在于它们在保证线程安全的同时不存在并发瓶颈。举个例子,ConcurrentHashMap采用了锁分段技术和弱一致性的Map迭代器去规避并发瓶颈。所以问题...
List,Map,Set三个接口存取元素时,各有什么特点?
Map特点:元素按键值对存储,无放入顺序 (应该知道什么是键值对吧!)List接口有三个实现类:LinkedList,ArrayList,Vector LinkedList:底层基于链表实现,链表内存是散乱的,每一个元素存储本身内存地址的同时还存储下一个元素的地址。链表增删快,查找慢 ArrayList和Vector的区别:ArrayList是非线程安全的,...
帮忙翻译下,谢谢了 100分送上
安全措施: 如何处理进入和外出的物品, 包括预防引进, 交易, 后失去任何合法或非法物件.2.Do you have a designated security officer to supervise the introduction \/ removal of cargo?你有没有指定的保安员监督货物的引进\/迁移?3.List and explain how products are properly marked, weighed, ...
为什么说ArrayList是线程不安全的
线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。 如图,List接口下面有两个实现,一个是ArrayList,另外一个是vector。 从源码的角度来看,因为Vector的方法前加了,synchronized 关键字,也就是同步的意思,sun公司希望Vector是线程安全的,而希望arraylist是...
JAVA中的List、Vector、ArrayList的差异
这意味着,和Vector相比,经过同步封装的LinkedList在性能上处于显著的劣势,因为Vector不需要为了线程安全而进行任何额外的间接调用。如果你想要有一个线程安全的LinkedList,你可以复制LinkedList类并让几个必要的方法同步,这样你可以得到一个速度更快的实现。对于所有其它集合类,这一点都同样有效:只有List...
ArrayList和List有什么区别?
内部数据结构:ArrayList底层是用动态数组实现的,而List底层可能是链表或者动态数组。这使得ArrayList在随机访问元素时(即通过索引访问元素)速度更快,但在添加或删除元素时速度可能会慢一些。而链表结构的List在插入和删除元素时速度更快。线程安全性:ArrayList是线程不安全的,如果在多线程环境下进行操作...
List集合是什么类型的集合
List集合包括JavaList接口以及List接口的所有实现类。List集合中的元素允许重复,各元素的顺序放是对象插入的顺序,类似Java中的数组,用户可通过使用索引(元素在集合中的位置)来访问集合中的元素。List的最重要的特征就是有序;它会确保以一定的顺序保存元素。List在Collection的基础上添加了大量方法,使之...
java中 List 与Set 的区别
尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。同步性Vector是同步的。这个类中的一些方法保证了Vector中的对象是线程安全的。而ArrayList则是异步的,因此ArrayList中的对象并不是线程安全的。因为同步的要求会影响执行的效率...
铎送正大: 你说的是java还是C++? java中解决这个问题通常有两种方法 一:使用synchronized关键字; 二:使用Collections.synchronizedList(); 假如你创建的代码如下:List<Map<String,Object>> data=new ArrayList<Map<String,Object>>(); 那么...
大方县15133149470: C++程序中有哪些线程安全机制 - ?
铎送正大: 回答这个问题的时候,首先要弄明白什么叫做线程安全.借用百度百科的解释:线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用.当然,在我看来这个解释是有问题的,因为数据的读取是不存在安全不安全的,因为你的数据不会发生改变,所以无论什么情况数据都是安全的.同样,如果只有写的操作也不会存在不安全,因为你只写,完全不管这个数据有没有效.只有同时涉及到读和写的操作的时候才会有安全之说.个人见解.加锁机制基本有一下4种:1、原子操作2、旋转锁3、临界区4、Silm锁
大方县15133149470: java list是不是线程安全的 - ?
铎送正大: 直接用Vector就可以了,它是线程安全的.ArrayList list=new ArrayList();就需要锁了,涉及同步,可以参考网上买票例子做.
大方县15133149470: ArrayList、LinkedList、Vector之间的区别是什么? - ?
铎送正大: ArrayList底层是数组实现的,而LinkedList是链表实现的.Vector和ArrayList一样是数组实现的,二者的差别在于:Vector是线程安全的,所以性能上不如ArrayList
大方县15133149470: ArrayList和LinkedList都是线程安全的吗? - ?
铎送正大: 都是线程安全的. ArrayList和LinkedList的区别及其优缺点 ArrayList和LinkedList的大致区别: 1. ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构. 2. 对于随机访问get和set,ArrayList觉得优于LinkedList,因为...
大方县15133149470: java arryList 线程安全问题 - ?
铎送正大: 在Collections工具类中有这样的方法:staticList synchronizedList(List list) 返回线程安全的集合 还有这种的set maP的你看看API文档
大方县15133149470: jdbc是否线程安全 - ?
铎送正大: 线程兼容类不是线程安全的,但是可以通过正确使用同步而在并发环境中安全地使用.这可能意味着用一个 synchronized 块包围每一个方法调用,或者创建一个包装器对象,其中每一个方法都是同步的(就像 Collections.synchronizedList() 一样).也可能意味着用 synchronized 块包围某些操作序列.为了最大程度地利用线程兼容类,如果所有调用都使用同一个块,那么就不应该要求调用者对该块同步.这样做会使线程兼容的对象作为变量实例包含在其他线程安全的对象中,从而可以利用其所有者对象的同步.JDBC是现成兼容类
大方县15133149470: vector和arraylist的区别 - ?
铎送正大: vector 安全 arraylist线程不安全 一、从存储数据的方式来看:1、ArrayList是采用数组方式存储数据,实现了可变大小的数组.它允许所有元素,包括null.其特点:(1)ArrayList没有同步.(2)此数组元素数大于实际存储的数据...
大方县15133149470: JAVA中线程安全的map有哪些? - ?
铎送正大: JAVA中线程安全的map有:Hashtable、synchronizedMap、ConcurrentHashMap.java中map中线程安全怎么实现:1. 同步的map就是Hashtable, concurrenthashmap.2. 你看到的Hashtable就是直接在hashmap上加了个锁,concurrenthashmap...
大方县15133149470: Java中StringBuffer 、ArrayList是线程安全的吗 - ?
铎送正大: ArrayList不是线程安全的 你看API如果他们的方法定义里面有synchronized证明是线程安全的 StringBuffer是线程安全的