Java 中数组列表的同步
原文:https://www . geesforgeks . org/synchronization-ArrayList-Java/
默认情况下,数组列表的实现不同步。这意味着如果一个线程在结构上修改它,并且多个线程同时访问它,那么它必须在外部同步。结构修改意味着从列表中添加或删除元素,或者显式调整支持数组的大小。更改现有元素的值不是结构修改。
创建同步数组列表有两种方法。
1.Collections.synchronizedList()方法。 2。使用 CopyOnWriteArrayList。
方法 1:使用 Collections.synchronizedList()方法
要进行串行访问,必须通过返回的列表完成对后备列表的所有访问。用户在迭代返回的列表时,必须手动对其进行同步。
public static List<T> synchronizedList(List<T> list)
- 接受一个列表,该列表可以是列表界面的实现。例如数组列表、链接列表。
- 返回由指定列表支持的同步(线程安全)列表。
- 参数列表是要包装在同步列表中的列表。
- t 代表通用
Java 语言(一种计算机语言,尤用于创建网站)
// Java program to demonstrate working of
// Collections.synchronizedList
import java.util.*;
class GFG
{
public static void main (String[] args)
{
List<String> list =
Collections.synchronizedList(new ArrayList<String>());
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());
}
}
}
Output
practice
code
quiz
方法 2:使用 CopyOnWriteArrayList
CopyOnWriteArrayList<T> threadSafeList = new CopyOnWriteArrayList<T>();
- 创建一个空列表。
- 实现列表界面。
- 它是数组列表的线程安全变体。
- t 代表泛型
数组列表的线程安全变体,其中所有的变异操作(例如,添加、设置、移除..)是通过创建底层数组的单独副本来实现的。它通过创建一个单独的列表副本来实现线程安全,该副本不同于用于提供线程安全的 vector 或其他集合。
- 当您不能或不想同步遍历但需要防止并发线程之间的干扰时,这很有用。
- 由于每次写入操作(例如,添加、设置、删除)都涉及单独的阵列拷贝,因此成本很高。)
- 当你有列表需要遍历它的元素并且不经常修改的时候,效率非常高。
迭代器不会抛出ConcurrentModificationException,即使一旦创建了迭代器,copyOnWriteArrayList 就会被修改。当对数组列表的另一个副本进行写操作时,迭代器正在对数组列表的单独副本进行迭代。
Java 语言(一种计算机语言,尤用于创建网站)
// 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<String> threadSafeList
= new CopyOnWriteArrayList<String>();
// 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<String> it = threadSafeList.iterator();
while (it.hasNext())
System.out.println(it.next());
}
}
Output
Elements of synchronized ArrayList :
geek
code
practice
如果我们试图通过 迭代器的方法修改 CopyOnWriteArrayList,会发生什么?
如果您试图通过迭代器自己的方法(例如 add()、set()、remove())修改copy onwriterarraylist,它将引发 UnsupportedOperationException。
Java 语言(一种计算机语言,尤用于创建网站)
// 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<String> threadSafeList =
new CopyOnWriteArrayList<String>();
// 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<String> it = threadSafeList.iterator();
while (it.hasNext())
{
String str = it.next();
it.remove();
}
}
}
运行时错误:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.concurrent.CopyOnWriteArrayList$COWIterator.remove
(CopyOnWriteArrayList.java:1176)
at GFG.main(File.java:28)
CopyOnWriteArrayList 的其他构造函数
1.copy onwriterarraylist(集合<?扩展 E > c) :创建一个包含指定集合元素的列表,按照集合迭代器返回元素的顺序。
2.copy onwriterarraylist(E[]to copy in):创建一个包含给定数组副本的列表。
向量同步时为什么要用 ArrayList?
- 性能: Vector 是同步的和线程安全的,正因为如此,它比 ArrayList 稍慢。
- 功能:矢量在每个单独操作的级别上同步。一般来说,程序员喜欢同步整个操作序列。同步单个操作既不太安全,也较慢。
- 向量过时:向量在 java 中被认为是过时的,并且被非正式地否决了。此外,向量在几乎从未完成的每个单独操作上同步。大多数 java 程序员更喜欢使用 arrayList,因为如果需要同步,他们可能会显式地同步 ArrayList。
本文由 Nitsdheerendra 供稿。如果你喜欢 GeeksforGeeks 并想投稿,你也可以使用write.geeksforgeeks.org写一篇文章或者把你的文章邮寄到 review-team@geeksforgeeks.org。看到你的文章出现在极客博客主页上,帮助其他极客。如果你发现任何不正确的地方,或者你想分享更多关于上面讨论的话题的信息,请写评论。
版权属于:月萌API www.moonapi.com,转载请注明出处