为什么以下Vector代码完全被破坏?

时间:2015-03-03 10:30:45

标签: java synchronization

来自:   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从标记向量中弃用至少?

2 个答案:

答案 0 :(得分:3)

  

矢量类是否在其自己的对象(this)上未同步?

是的,但仅适用于每项操作。

这里我们有两个操作:

if (vector.isEmpty())
    vector.add(anElement);

在检查isemptyadd调用之间,可能会有另一个线程添加项目。修复方法是通过组合操作添加同步:

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        |

因此,您可以看到单个操作是线程安全的,但整个事务不是。