如何正确使用SynchronizedList?
操作List,已经做了
同步synchronized,还会有ConcurrentModificationException,知道为什么吗?
1.
class="java" name="code">
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;
}
}