来自: Synchronization in Vectors in Java
为什么在考虑同步时会破坏以下代码?
矢量类是否在其自己的对象(this
)上未同步?
// BROKEN CODE, needs external synchronization
// only add an element if the vector is empty
if(vector.isEmpty())
vector.add(anElement);
更新:
通过下面的答案(来自jon Skeet和Pshemo),它不会使向量几乎无用(我们有arraylist)吗?
因为无论如何我们需要手动同步以用于任何实际用途。 如果是,那么什么阻止Java从标记向量中弃用至少?
答案 0 :(得分:3)
矢量类是否在其自己的对象(this)上未同步?
是的,但仅适用于每项操作。
这里我们有两个操作:
if (vector.isEmpty())
vector.add(anElement);
在检查isempty
和add
调用之间,可能会有另一个线程添加项目。修复方法是通过组合操作添加同步:
synchronized (vector) {
if (vector.isEmpty()) {
vector.add(anElement);
}
}
答案 1 :(得分:2)
vector
的状态可以在if(vector.isEmpty())
测试和vector.add(anElement);
方法之间更改。其他线程可以简单地在这些操作之间添加一些元素。
我们希望仅在向量为空时将anElement
添加到向量。但是使用当前代码可能
Thread A | Thread B
---------------------------+---------------------------
take vector lock |
check if vector is empty |
release vector lock |
| take vector lock
| add `otherElement`
| release vector lock
take vector lock |
add `anElement` |
release vector lock |
因此,您可以看到单个操作是线程安全的,但整个事务不是。