Java Vector 线程安全

5

如果我在从多个线程访问时仅用于读取的情况下,在我的服务器程序中使用一个Vector(java.util.Vector),是否存在任何危险?(myvector .size() .get() ...)对于写入,我使用同步方法。谢谢。

4个回答

22

如上所述,由于使用了synchronized修饰符,Vector的每种方法本身都是线程安全的。 但是,如果您需要进行一些复杂的操作,例如基于与同一vector相关的条件的get()add(),则该操作不是线程安全的。请参见下面的示例:

if (vector.size() > 0) {
    System.out.println(vector.get(0));
}

这段代码存在一个竞争条件,在size()get()之间 - 向量的大小可能在我们的线程验证向量不为空后被其他线程更改,因此get()调用可能会返回意外的结果。为了避免这种情况,上面的示例应该更改如下:

synchronized (vector) {
    if (vector.size() > 0) {
        System.out.println(vector.get(0));
    }
}

现在这个“获取非空值”操作是原子的,没有竞态条件。


11

Vector是一个线程安全的集合 - 默认情况下它的所有方法都是同步的。这就是为什么建议使用ArrayList代替 - 它不是线程安全的,因此对于单线程应用程序会有更好的性能。


当然,如果在安全发布后没有线程写入数组,那么ArrayList是线程安全的。(但不要忘记,“没有线程”意味着连主线程也不能写入。) - Solomon Slow
1
为什么单线程应用程序会有差异?如果没有其他线程锁定synchronized方法,那么它不是几乎相同吗?即使没有锁定/阻塞,synchronized机制是否会增加这样的开销? - Nom1fan

3
The java.util.Vector方法都是同步的。因此从多个线程使用它是“安全”的。只有当您需要一个读取-计算-写入过程是原子的时候,才需要进行同步。同步您自己的方法并不一定使您的代码针对这些情况是线程安全的。如果共享状态是Vector对象,则需要在Vector实例上同步,而不是在自己类的实例上。

如果共享状态是Vector对象,则需要在Vector实例上进行同步。谢谢,这也帮了我很多 :) - Smarty77

1

向量类是线程安全的(大小,获取和设置方法都是同步的),但如果您想获得更好的性能,应该尝试使用CopyOnWriteArrayListCollections.synchronizedList


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接