我们说我有两个列表:fooList
和barList
。另外,让我们说我有两个线程:第一个迭代fooList,如果满足某些条件(条件为真),它会从fooList中删除元素并将其添加到barList。第二个迭代barList,如果某个其他条件为true,则从barList中删除元素,并将其添加到fooList。
我处理它的方式是:
private static Object sharedLock = new Object();
Thread t1 = new Thread() {
public void run() {
synchronized (sharedLock) {
for (Iterator<String> iterator = fooList.iterator(); iterator.hasNext();) {
String fooElement = iterator.next();
if (condition == true) {
iterator.remove();
barList.add(fooElement);
}
}
}
}
};
Thread t2 = new Thread() {
public void run() {
synchronized (sharedLock) {
for (Iterator<String> iterator = barList.iterator(); iterator.hasNext();) {
String barElement = iterator.next();
if (otherCondition == true) {
iterator.remove();
fooList.add(barElement);
}
}
}
}
};
我想知道的是我处理得当吗?是否存在竞争条件?有没有更好的方法来实现相同的功能?
编辑看起来正确的实现方式是:
Thread t1 = new Thread() {
public void run() {
for (String fooElement : fooList) {
if (condition == true) {
fooList.remove(fooElement);
barList.add(fooElement);
}
}
}
};
Thread t2 = new Thread() {
public void run() {
for (String barElement : barList) {
if (otherCondition == true) {
barList.remove(barElement);
fooList.add(barElement);
}
}
}
};
其中:fooList
和barList
都属于CopyOnWriteArrayList<String>
答案 0 :(得分:9)
答案 1 :(得分:2)
现在实现它的方式,t1
和t2
将按顺序运行,而不是并行运行。无论哪一个首先开始,声称锁,执行他的整个循环,终止并释放另一个锁。
好处是:没有竞争条件。不好的是:没有并行性。
一般来说,如果可以避免锁定,直接使用锁定是一个坏主意。 Java包含一系列专门用于并发使用的集合。见Java Concurrency Utils