Java中ArrayList的同步

默认情况下,ArrayList的实现不同步。这意味着,如果一个线程在结构上修改了它,并且多个线程同时访问它,那么它必须在外部同步。结构修改意味着从列表中添加或删除元素,或显式调整支持数组的大小。更改现有图元的值不是结构修改。

null

有两种方法可以创建同步的ArrayList。

1.收藏。synchronizedList()方法。 2.使用CopyOnWriteArrayList。

方法1:使用集合。synchronizedList()方法

要进行串行访问,必须通过返回的列表完成对支持列表的所有访问。用户必须 手动 在遍历返回的列表时对其进行同步。

public static  List<T> synchronizedList(List<T> list)
  • 接受一个列表,该列表可能是 列表 界面e、 g.ArrayList,LinkedList。
  • 返回由指定列表支持的同步(线程安全)列表。
  • 参数列表是要包装在同步列表中的列表。
  • 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());
}
}
}


输出

practicecodequiz

方法2:使用CopyOnWriteArrayList

CopyOnWriteArrayList<T> threadSafeList = new CopyOnWriteArrayList<T>();
  • 创建一个空列表。
  • 它实现了 列表 界面
  • 它是ArrayList的线程安全变体。
  • T代表泛型

ArrayList的一种线程安全变体,其中包含所有变异操作(例如,添加、设置、删除..)通过创建基础文件的单独副本来实现 大堆 。它通过创建列表的单独副本来实现线程安全,该副本不同于用于提供线程安全的vector或其他集合。

  • 当你不能或不想做的时候,它很有用 使同步 遍历还需要防止并发线程之间的干扰。
  • 它是 花钱多的 因为它涉及到单独的 数组副本 每次写入操作(例如,添加、设置、删除)
  • 当你有 列表 需要遍历它的元素,不要经常修改它。

迭代器不会抛出 ConcurrentModificationException 即使创建迭代器后修改了copyOnWriteArrayList。迭代器正在对ArrayList的单独副本进行迭代,而写操作正在对ArrayList的另一个副本进行。

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());
}
}


输出

Elements of synchronized ArrayList :geekcodepractice

如果我们试图通过 迭代器方法?

如果您试图修改,它会抛出UnsupportedOperationException CopyOnWriteArrayList 通过迭代器自己的方法(例如add()、set()、remove())。

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. CopyOnWriteArrayList(集合c) :创建一个包含指定集合元素的列表,按集合迭代器返回的顺序排列。

2. CopyOnWriteArrayList(E[]到copyin) :创建包含给定数组副本的列表。

向量同步时为什么使用ArrayList?

  1. 性能: 向量是 同步的 而且线程安全,正因为如此,它比ArrayList稍慢一些。
  2. 功能: 矢量在每个单独操作的级别进行同步。通常,程序员喜欢同步整个操作序列。同步单个操作既不安全,也较慢。
  3. 向量过时: 在java中,向量被认为是过时的,并被非正式地弃用。此外,向量在每个单独的操作上都是同步的,这几乎是从未完成过的。大多数java程序员更喜欢使用ArrayList,因为如果需要同步,他们可能会显式地同步ArrayList。

必须阅读: Java中的向量与数组列表

本文由 尼茨海伦德拉 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享