为什么以下 Vector 代码完全损坏?
Why is the following Vector code broken exactly?
来自:
Synchronization in Vectors in Java
考虑到同步,为什么下面的代码是错误的?
向量class在它自己的对象(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 至少将 vector 标记为已弃用?
vector
的状态可以在 if(vector.isEmpty())
测试和 vector.add(anElement);
方法之间切换。其他线程可以简单地在这些操作之间添加一些元素。
我们只想将 anElement
添加到 vector 中,前提是它是空的。但是使用当前代码可能
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 |
如您所见,单个操作是线程安全的,但整个事务不是。
Is the vector class not synchronized on its own object (this)?
是的,但仅限于每个单独的操作。
这里我们有两个操作:
if (vector.isEmpty())
vector.add(anElement);
在 isempty
的检查和 add
调用之间,不同的线程可能会添加一个项目。解决方法是在 combined 操作上添加同步:
synchronized (vector) {
if (vector.isEmpty()) {
vector.add(anElement);
}
}
来自: Synchronization in Vectors in Java
考虑到同步,为什么下面的代码是错误的?
向量class在它自己的对象(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 至少将 vector 标记为已弃用?
vector
的状态可以在 if(vector.isEmpty())
测试和 vector.add(anElement);
方法之间切换。其他线程可以简单地在这些操作之间添加一些元素。
我们只想将 anElement
添加到 vector 中,前提是它是空的。但是使用当前代码可能
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 |
如您所见,单个操作是线程安全的,但整个事务不是。
Is the vector class not synchronized on its own object (this)?
是的,但仅限于每个单独的操作。
这里我们有两个操作:
if (vector.isEmpty())
vector.add(anElement);
在 isempty
的检查和 add
调用之间,不同的线程可能会添加一个项目。解决方法是在 combined 操作上添加同步:
synchronized (vector) {
if (vector.isEmpty()) {
vector.add(anElement);
}
}