有一个简单的任务:多个线程调用
我的问题是:哪种解决方案更好或更有效?
第三种方法:使用
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;
}
}
synchronized
块之前修改循环内的列表。 - SLaksCollections.synchronized*()
是无用的众多原因之一。 - SLaks