Java 为什么下面的向量代码被完全破坏了?

Java 为什么下面的向量代码被完全破坏了?,java,synchronization,Java,Synchronization,下表出自: 就同步而言,为什么下面的代码会被破坏? vector类是否未在其自己的对象上同步(this) 更新: 根据下面的答案(来自jon Skeet和Pshemo),向量实际上不是毫无用处吗(我们有arraylist) 因为我们需要手动同步任何实际用途。 如果是,是什么阻止Java至少将vector标记为不推荐的?vector的状态可以在If(vector.isEmpty())test和vector.add(anElement)之间更改方法。其他线程可以简单地在这些操作之间添加一些元素 仅

下表出自:

就同步而言,为什么下面的代码会被破坏? vector类是否未在其自己的对象上同步(
this

更新:

根据下面的答案(来自jon Skeet和Pshemo),向量实际上不是毫无用处吗(我们有arraylist)

因为我们需要手动同步任何实际用途。
如果是,是什么阻止Java至少将vector标记为不推荐的?

vector的状态可以在
If(vector.isEmpty())
test和
vector.add(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        |

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

向量的状态可以在
if(vector.isEmpty())
test和
vector.add(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        |
正如您所看到的,单个操作是线程安全的,但整个事务不是

vector类是否未在其自身对象上同步(此)

是的,但仅适用于每个单独的操作

这里我们有两个操作:

if (vector.isEmpty())
    vector.add(anElement);
有可能在检查
isempty
add
调用之间,另一个线程可以添加一个项目。修复方法是在组合操作上添加同步:

synchronized (vector) {
    if (vector.isEmpty()) {
        vector.add(anElement);
    }
}
vector类是否未在其自身对象上同步(此)

是的,但仅适用于每个单独的操作

这里我们有两个操作:

if (vector.isEmpty())
    vector.add(anElement);
有可能在检查
isempty
add
调用之间,另一个线程可以添加一个项目。修复方法是在组合操作上添加同步:

synchronized (vector) {
    if (vector.isEmpty()) {
        vector.add(anElement);
    }
}

@fge:知识永远不会伤害:预先记录您的更新:如果我没记错的话,单个操作的同步将使我们免于不一致的状态,例如由种族引起的状态。在调用
add(foo)
add(bar)时使用同步
当我们尝试放置一个元素,而vector使用的内部数组需要调整大小以存储更多元素,并且新元素将被放置在旧数组中,例如,在被存储所有元素的新数组替换之前,我们确信这两种方法都将正确执行,而不必担心可能出现的问题元素。是的,向量实际上是无用的。也就是说,我的理解是,如果不打算删除某些内容,Java不会反对它们,而且太多的遗留代码依赖于Vector来删除它们。@fge:Knowledge-never-hat:PRegarding-your-update:如果我没记错的话,单个操作的同步可以将我们从不一致的状态中拯救出来,例如由种族引起的不一致状态。在调用
add(foo)
add(bar)时使用同步
当我们尝试放置一个元素,而vector使用的内部数组需要调整大小以存储更多元素,并且新元素将被放置在旧数组中,例如,在被存储所有元素的新数组替换之前,我们确信这两种方法都将正确执行,而不必担心可能出现的问题元素。是的,向量实际上是无用的。也就是说,我的理解是,如果不打算删除某些东西,Java不会反对它们,而且太多遗留代码依赖于Vector来删除它们。