【发布时间】:2013-12-13 08:46:39
【问题描述】:
有一个简单的任务:许多线程调用MyClass.add() 函数,一个线程尝试为它们服务。
我的问题:哪个是更好或更有效的解决方案?
第一种方法:CopyOnWriteArrayList
@Singleton
public class myClass {
List<myType> list = new CopyOnWriteArrayList<myType>();
boolean isRunning = false;
//this is called from many threads
public void add(myType x){
list.add(x);
}
//this is called from 1 thread
public void start(){
if (isRunning) return;
isRunning = true;
while (!list.isEmpty()) {
myType curr = list.remove(0);
//do something with curr...
}
isRunning = false;
}
}
使用简单锁的第二种方法:
@Singleton
public class myClass {
List<myType> list = new ArrayList<myType>();
boolean isRunning = false;
private final Lock _mutex = new ReentrantLock(true);
//this is called from many threads
public void add(myType x){
_mutex.lock();
list.add(x);
_mutex.unlock();
}
//this is called from 1 thread
public void start(){
if (isRunning) return;
isRunning = true;
while (!list.isEmpty()) {
_mutex.lock();
myType curr = list.remove(0);
_mutex.unlock();
//do something with curr...
}
isRunning = false;
}
}
第三种方法:ConcurrentLinkedQueue
@Singleton
public class myClass {
ConcurrentLinkedQueue<myType> list = new ConcurrentLinkedQueue<myType>();
boolean isRunning = false;
//this is called from many threads
public void add(myType x){
list.add(x);
}
//this is called from 1 thread
public void start(){
if (isRunning) return;
isRunning = true;
while (!list.isEmpty()) {
//list cannot be empty at this point: other threads can't remove any items
myType curr = list.poll();
//do something with curr...
}
isRunning = false;
}
}
这是最初的错误解决方案。我不知道为什么它有时会给出(>100 个线程)ConcurrentModificationException(尽管有迭代器和“同步”):
@Singleton
public class myClass {
List<myType> list = Collections.synchronizedList(new ArrayList<myType>());
boolean isRunning = false;
//this is called from many threads
public void add(myType x){
synchronized(list) {
list.add(x);
}
}
//this is called from 1 thread
public void start(){
if (isRunning) return;
isRunning = true;
for (ListIterator<myType> iter = list.listIterator(); iter.hasNext();){
myType curr = iter.next();
//do something with curr...
synchronized(list) {
iter.remove(); //sometime it gives ConcurrentModificationException!
}
}
isRunning = false;
}
}
【问题讨论】:
-
这取决于你的目标是什么。
-
似乎是一个快速的性能包装器,它分叉 X 线程,使 Y 队列事务按顺序排列。加油!
-
你原来的错误解决方案并不能阻止其他线程在
synchronized块之前修改循环内的列表。 -
这是
Collections.synchronized*()无用的众多原因之一。
标签: java multithreading arraylist queue