Nacos源码阅读方法
273
2022-08-19
Java中ArrayList同步的2种方法分享
目录方法1:使用Collections.synchronizedList()方法方法2:使用CopyOnWriteArrayList向量同步时为什么要使用arrayList?
前言:
arrayList 的实现是默认不同步的。这意味着如果一个线程在结构上修改它并且多个线程同时访问它,它必须在外部同步。结构修改意味着从列表中添加或删除元素或显式调整后备数组的大小。改变现有元素的值不是结构修改。
有两种方法可以创建同步Arraylist:
1. Collections.synchronizedList() 方法。2. 使用 CopyOnWriteArrayList。
方法1:使用 Collections.synchronizedList() 方法
要进行串行访问,必须通过返回列表完成对后备列表的所有访问。
在迭代返回的列表时,用户必须手动同步它。因为在执行add()等方法的时候是加了synchronized关键字的,但是iterator()却没有加。所以在使用的时候需要加上synchronized。
// java program to demonstrate working of
// Collections.synchronizedList
import java.util.*;
class GFG
{
public static void main (String[] args)
{
List
Collections.synchronizedList(new ArrayList
list.add("practice");
list.add("code");
list.add("quiz");
synchronized(list)
{
// must be in synchronized block
Iterator it = list.iterator();
while (it.hasNext())
System.out.println(it.next());
}
}
}
方法 2:使用 CopyOnWriteArrayList
ArrayList 的线程安全变体,其中所有可变操作(例如添加、设置、删除...)都是通过创建底层数组的单独副本来实现的。它通过创建 List 的单独副本来实现线程安全,这与 vector 或其他集合用于提供线程安全的方式不同。
当我们不能或不想同步遍历,但需要防止并发线OBUmcBw程之间的干扰时,它很有用。这是昂贵的,因为每次写入操作都涉及单独的数组副本(例如添加,设置,删除......)当你有List并且需要遍历它的元素并且不经常修改它时,它是非常有效的。
即使在创建迭代器后修改了 copyOnWriteArrayList,迭代器也不会抛出ConcurrentModificationException,因为迭代器正在迭代 ArrayList 的单独副本,而写操作正在 ArrayList 的另一个副本上发生。
// Java program to illustrate the thread-safe ArrayList.
import java.io.*;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
class GFG
{
public static void maihttp://n (String[] args)
{
// creating a thread-safe Arraylist.
CopyOnWriteArrayList
= new CopyOnWriteArrayList
// Adding elements to synchronized ArrayList
threadSafeList.add("geek");
threadSafeList.add("code");
threadSafeList.add("practice");
System.out.println("Elements of synchronized ArrayList :");
// Iterating on the synchronized ArrayList using iterator.
Iterator
while (it.hasNext())
System.out.println(it.next());
}
}
如果我们尝试通过迭代器自己的方法修改 CopyOnWriteArrayList 会发生什么?
如果您尝试通过迭代器自己的方法(例如 add()、set()、remove())修改CopyOnWriteArrayList,它会抛出 UnsupportedOperationException 。
// Java program to illustrate the thread-safe ArrayList
import java.io.*;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
class GFG
{
public static void main (String[] args)
{
// creating a thread-safe Arraylist.
CopyOnWriteArrayList
new CopyOnWriteArrayList
// Adding elements to synchronized ArrayList
threadSafeList.add("geek");
threadSafeList.add("code");
threadSafeList.add("practice");
System.out.println("Elements of synchronized ArrayList :");
// Iterating on the synchronized ArrayList using iterator.
Iterator
while (it.hasNext())
{
String str = it.next();
it.remove();
}
}
}
CopyOnWriteArrayList 的其他构造函数:
1. CopyOnWriteArrayList(Collection extends E> c):创建一个包含指定集合元素的列表,按照集合迭代器返回的顺序。2. CopyOnWriteArrayList(E[] toCopyIn):创建一个包含给定数组副本的列表。
向量同步时为什么要使用arrayList?
性能: Vector 是同步和线程安全的,因此,它比 ArrayList 稍慢。功能: Vector 在每个单独的操作级别进行同步。通常,程序员喜欢同步整个操作序列。同步单个操作既不安全又慢。Vectors obsolete:向量被认为是过时的,并且在 java 中被非正式地弃用。此外,vector 对几乎从未完成的每个单独操作进行同步。大多数java程序员更喜欢使用ArrayList,因为如果他们需要进行同步,他们可能无论如何都会显式地同步arrayList。
以下是 Java 中 ArrayList 和 CopyOnWriteArrayList 类之间的显着差异。
数组列表复制写入数组列表同步ArrayList 不同步。CopyOnWriteArrayList 是同步的。线程安全ArrayList 不是线程安全的。CopyOnWriteArrayList 是线程安全的。迭代器类型ArrayList 迭代器是快速失败的,如果在迭代过程中发生并发修改,则 ArrayList 会抛出 ConcurrentModificationException。CopyOnWriteArrayList 是故障安全的,它在迭代过程中永远不会抛出 ConcurrentModificationException。其背后的原因是 CopyOnWriteArrayList 每次修改时都会创建一个新的数组列表。删除操作ArrayList 迭代器支持在迭代过程中移除元素。如果在迭代期间尝试删除元素,则 CopyOnWriteArrayList.remove() 方法会引发异常。表现ArrayList 更快。CopyOnWriteArrayList 比 ArrayList 慢。从 Java 版本开始1.21.5
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~