如何正确使用SynchronizedList?
操作List,已经做了同步synchronized,还会有ConcurrentModificationException,知道为什么吗?
1.
static class SynchronizedList<E>
extends SynchronizedCollection<E>
implements List<E> {
private static final long serialVersionUID = -7754090372962971524L;
final List<E> list;
SynchronizedList(List<E> list) {
super(list);
this.list = list;
}
SynchronizedList(List<E> list, Object mutex) {
super(list, mutex);
this.list = list;
}
public boolean equals(Object o) {
if (this == o)
return true;
synchronized (mutex) {return list.equals(o);}
}
public int hashCode() {
synchronized (mutex) {return list.hashCode();}
}
public E get(int index) {
synchronized (mutex) {return list.get(index);}
}
public E set(int index, E element) {
synchronized (mutex) {return list.set(index, element);}
}
public void add(int index, E element) {
synchronized (mutex) {list.add(index, element);}
}
public E remove(int index) {
synchronized (mutex) {return list.remove(index);}
}
public int indexOf(Object o) {
synchronized (mutex) {return list.indexOf(o);}
}
public int lastIndexOf(Object o) {
synchronized (mutex) {return list.lastIndexOf(o);}
}
public boolean addAll(int index, Collection<? extends E> c) {
synchronized (mutex) {return list.addAll(index, c);}
}
[b]public ListIterator<E> listIterator() {
return list.listIterator(); // Must be manually synched by user
}
public ListIterator<E> listIterator(int index) {
return list.listIterator(index); // Must be manually synched by user
}[/b]
}
static class SynchronizedCollection<E> implements Collection<E>, Serializable {
private static final long serialVersionUID = 3053995032091335093L;
final Collection<E> c; // Backing Collection
final Object mutex; // Object on which to synchronize
[b]SynchronizedCollection(Collection<E> c) {
this.c = Objects.requireNonNull(c);
mutex = this;
}[/b]
2. 可以看出这个类的大多数方法通过同步块实现,
List<User> list = Collections.synchronizedList();
锁为synchronizedList.
3. iterator. stream, parallelStream 多线程操作必须用户自己实现同步
同步方法
package perf;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class Test {
public static void main(String[] args) throws InterruptedException {
List<User> list = Collections.synchronizedList(new ArrayList<User>());
// lock
final List<User> mutex = list;
for (int i = 0; i < 100000; i++) {
User user = new User();
user.setName("" + i);
list.add(user);
}
System.out.println("list = " + list.size());
new Thread(new Runnable() {
@Override
public void run() {
// use lock
synchronized (mutex) {
for (Iterator<User> it = list.iterator(); it.hasNext();) {
User user = it.next();
if (user.getName().indexOf("9") != -1) {
it.remove();
}
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
// use lock
synchronized (mutex) {
for (Iterator<User> it = list.iterator(); it.hasNext();) {
User user = it.next();
if (user.getName().indexOf("8") != -1) {
it.remove();
}
}
}
}
}).start();
Thread.currentThread().sleep(1000L);
System.out.println("list = " + list.size());
System.out.println("list = " + list.isEmpty());
}
}
class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
分享到:
相关推荐
标题中的"Collections.synchronizedList"是指Java集合框架中的一个静态工厂方法,用于将任何List转换为线程安全的List。这个方法是Java中实现多线程环境下的集合操作的重要工具,确保在并发访问时数据的一致性和完整...
`SynchronizedList`和`Vector`都是提供线程安全保证的列表实现,但它们在实现方式和性能上存在一些差异。下面我们将深入探讨这两个类的区别。 1. **实现方式** - `Vector` 是 `java.util` 包中的一个类,它直接...
疑问:同样都是加了锁的集合,为什么synchronizedList比Vector快呢? 探究ArrayList为什么查询快、增删慢,实现add方法底层原理详解 ArrayList源码分析(基于JDK8) 因为Vector和ArrayList除了数组扩容有点差别,...
Spring数据mongodb测试 在Collections.synchronizedList或Collections.synchronizedSet上测试spring数据mongodb ConcurrentModificationException
2. 使用`Collections.synchronizedList(new ArrayList)`: 这种方法通过装饰器模式,将传入的`ArrayList`包装成`synchronizedList`,对所有调用的方法添加了同步控制。这样在并发环境下,多个线程调用`add()`等方法时...
在实际开发中,如果对线程安全有需求,可以考虑使用Collections.synchronizedList()方法将ArrayList转换为线程安全的列表,或者使用CopyOnWriteArrayList,这是一个更适合并发读写场景的线程安全实现。而如果在单...
此外,ArrayList不是线程安全的,如果在多线程环境中使用,需要通过Collections.synchronizedList方法使ArrayList同步。 二、ArrayList源码分析 1. 底层实现:ArrayList的内部字段`elementData`是一个transient的...
2. 使用`Collections.synchronizedList`:这个静态方法可以将给定的`ArrayList`转换为线程安全的列表。在内部,它通过在方法调用上添加`synchronized`关键字来实现同步。这提供了线程安全的访问,但仍然需要谨慎处理...
因此,如果需要在多线程环境下使用List,应该选择Vector或使用Collections.synchronizedList()方法来将List转换为线程安全的集合。 3.List是有序的吗? 是的,List是有序的。List中元素的顺序是固定的,可以使用...
2. 使用`Collections.synchronizedList()`:Java标准库提供了同步包装器,将普通集合转换为线程安全的集合,如`List`可以通过`Collections.synchronizedList()`进行转换。 3. 使用`ReentrantLock`:如果需要更细...
为了在多线程环境下安全地使用ArrayList,可以借助`Collections.synchronizedList`方法将其包装成线程安全的列表。例如: ```java List, Object>> test = Collections.synchronizedList(new ArrayList, Object>>())...
如果没有这样的对象存在,列表应该使用Collections.synchronizedList方法“包装”。 这最好在创建时完成,以防止意外的不同步访问列表: List list = Collections.synchronizedList(new ArrayList(...)); The ...
private List<String> list = Collections.synchronizedList(new ArrayList()); public void run() { synchronized (list) { Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { ...
如果该对象不存在,该列表应被“包装”使用Collections.synchronizedList方法。 这最好在创建时完成,以防止意外的名单不同步访问: List list = Collections.synchronizedList(new ArrayList(...)); 此类的返回的...
- 使用 `Collections.synchronizedList()`:这个静态工厂方法会返回一个线程安全的 List 实例,它是原有 List 的包装器。例如: ```java List, Object>> data = Collections.synchronizedList(new ArrayList, ...
`ArrayList`是非线程安全的,多线程环境下需要通过`Collections.synchronizedList()`来保证安全性。在给定的例子中,如果`A`类的`equals()`方法始终返回`true`,那么`remove(new A())`会删除列表的第一个元素,因为`...
例如,`Collections.synchronizedList`和`Collections.synchronizedMap`。同步集合在每个方法上加锁,确保同一时间只有一个线程可以执行操作。虽然提供了基本的线程安全性,但它们不是高度优化的并发解决方案,因为...