我有一个我在两个线程之间共享的arrayList,我正在尝试迭代并同时修改列表。我不想使用迭代器的方法,我也使用了同步列表,但它仍然提供concurrentmodificationexception
。
代码如下:
public class testing {
public static void main(String args[]){
ArrayList<String> al = new ArrayList<String>();
List<String> sal=Collections.synchronizedList(al);
String names[] = {"amol","Robin","vikas","shanu","mahesh"};
for(String x :names){
al.add(x);
}
Thread t1 = new Thread(new SyncArrayList(sal));
Thread t2 = new Thread(new SyncArrayList(sal));
t1.setName("T1");
t2.setName("T2");
t1.start();
t2.start();
}
}
class SyncArrayList implements Runnable
{
List<String> unsync ;
SyncArrayList(List<String> l){
this.unsync = l;
}
@Override
public void run() {
displayUnsyncList();
addNames();
}
void displayUnsyncList(){
synchronized(this){
ListIterator<String> itr = unsync.listIterator();
while(itr.hasNext()){
String x = itr.next();
System.out.println("Thread " +Thread.currentThread().getName() + " is displaying name : "+x);
}
}
}
void addNames(){
unsync.add("preet");
}
}
答案 0 :(得分:2)
在多线程环境中,您应该考虑使用CopyOnWriteArrayList
来生成ConcurrentModificationException
答案 1 :(得分:1)
Collections.synchronizedList(...)
的{{3}}解释了您需要做的事情:
void displayUnsyncList() {
synchronized (unsync) {
ListIterator<String> itr = unsync.listIterator();
while (itr.hasNext()) {
String x = itr.next();
System.out.println("Thread " +
Thread.currentThread().getName() +
" is displaying name : " + x);
}
}
简而言之,您的代码正在同步错误的对象。
答案 2 :(得分:0)
您正在使用的迭代器是fail-fast iterator.Fail-fast迭代器直接读取内部数据结构。迭代整个集合时不应修改内部数据结构。
当一个或多个线程在集合上进行迭代时,您应该使用故障安全迭代器,在这两个线程之间,一个线程会更改集合的结构。
public static void main(String args[]) {
ArrayList<String> al = new ArrayList<String>();
List<String> sal = Collections.synchronizedList(al);
String names[] = { "amol", "Robin", "vikas", "shanu", "mahesh" };
for (String x : names) {
al.add(x);
}
Thread t1 = new Thread(new SyncArrayList(sal));
Thread t2 = new Thread(new SyncArrayList(sal));
t1.setName("T1");
t2.setName("T2");
t1.start();
t2.start();
}
}
类SyncArrayList实现Runnable { 列出unsyn;
// List<String> unsync = Collections.synchronizedList(unsyn);
SyncArrayList(List<String> l) {
this.unsyn = new CopyOnWriteArrayList<String>(l);
}
@Override
public void run() {
displayUnsyncList();
addNames();
}
void displayUnsyncList() {
synchronized (this) {
Iterator<String> it = unsyn.iterator();
while (it.hasNext()) {
System.out.println("Thread " + Thread.currentThread().getName() + " is displaying name : " + it.next());
}
}
}
void addNames() {
unsyn.add("preet");
}