`
talentluke
  • 浏览: 600815 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Vector 是线程安全的?

 
阅读更多

Vector 是否是线程安全的?因为框架大量使用 RMI,RMI 是天生非线程安全的,所以作者认为采用了 Vector 来声明成员变量后,类就是 Thread-safe 了。

或许,大家经常也碰到类似的问题:Vector 与 ArrayList 的区别?
好多人一拍脑门就出:Vector 是线程安全的 (在任何情况下都是)。。。

原因可能是因为 Vector 的所有方法加上了 synchronized 关键字,从而保证访问 vector 的任何方法都必须获得对象的 intrinsic lock (或叫 monitor lock),也即,在vector内部,其所有方法不会被多线程所访问。
但是,以下代码呢:

if (!vector.contains(element)) 
    vector.add(element); 
    ...
}

这是经典的 put-if-absent 情况,尽管 contains, add 方法都正确地同步了,但作为 vector 之外的使用环境,仍然存在  race condition: 因为虽然条件判断 if (!vector.contains(element))与方法调用 vector.add(element);  都是原子性的操作 (atomic),但在 if 条件判断为真后,那个用来访问vector.contains 方法的锁已经释放,在即将的 vector.add 方法调用 之间有间隙,在多线程环境中,完全有可能被其他线程获得 vector的 lock 并改变其状态, 此时当前线程vector.add(element);  正在等待(只不过我们不知道而已)。只有当其他线程释放了 vector 的 lock 后,vector.add(element); 继续,但此时它已经基于一个错误的假设了。

单个的方法 synchronized 了并不代表组合(compound)的方法调用具有原子性,使 compound actions  成为线程安全的可能解决办法之一还是离不开
intrinsic lock (这个锁应该是 vector 的,但由 client 维护)

// Vector v = ...
    public  boolean putIfAbsent(E x) {
synchronized(v) { 
            boolean absent = !contains(x); 
            if (absent) { 
                add(x);

}
        return absent; 
    }

所以,正确地回答那个“愚蠢”的问题是:
Vector 和 ArrayList 实现了同一接口 List, 但所有的 Vector 的方法都具有 synchronized 关键修饰。但对于复合操作,Vector 仍然需要进行同步处理。 

这样做的后果,Vector 应该尽早地被废除,因为这样做本身没有解决多线程问题,反而,在引入了概念的混乱的同时,导致性能问题,因为 synchronized 的开销是巨大的:阻止编译器乱序,hint for 处理器寄存一/二级缓存。。。

分享到:
评论
6 楼 charles751 2017-06-18  
分析的很好!
但有一点:只要同步组合操作就可以了,不一定非要synchronzed(Vector)。
5 楼 S346618898 2016-02-26  
core Java中有一段:
Vector类对自己的所有可修改方法
都使用内部锁。然而,这是真的吗? Vector类的文档没有给出这样的承诺。不得不仔细研究源
代码并希望将来的版本能介绍非同步的可修改方法。如你所见,客户端锁定是非常脆弱的,通
常不推荐使用。
4 楼 xd2008ck 2015-08-18  
各自有各自的场景吧
楼主不要太激进了
3 楼 zwt2001267 2015-05-10  
写的不错,赞一个
2 楼 primer_of_java 2014-04-29  
楼主善于思考这点是很不错的. 点赞.
最近在面试的时候我遇到了让我写多线程,然后我使用了vector,果然也遇到了楼主描述的这个问题,因此不得不用同步块来完成原子操作~~
1 楼 fortunely 2014-04-24  
分析得不错,学习了,赞一个。
那最主要的区别其实是不是就是Vector的每个函数实现都加了sychronized关键字

相关推荐

    线程安全Vector

    ### 线程安全Vector详解 #### 一、线程安全的基本概念 在软件开发中,尤其是在并发编程领域,线程安全是一个极为重要的概念。它指的是一个类或一段代码能够被多个线程同时调用而不会导致数据不一致或其他错误的...

    servlet线程安全问题

    2. 使用线程安全的对象:使用线程安全的对象,如 Vector、Hashtable 等,而不是 ArrayList、HashMap 等。 3. 使用锁机制:使用锁机制,如 synchronized 关键字,可以锁定某个对象,以避免多个线程同时访问同一个对象...

    Go-golang-set-Go的线程安全的和非线程安全的高性能集

    `golang-set`库提供了一种实现,包括线程安全和非线程安全的高性能集,非常适合在Go的并发环境中使用。 首先,我们要理解什么是线程安全和非线程安全。线程安全指的是在多线程环境下,一个函数或方法在同一时刻可以...

    c++ stl线程安全

    5. 使用线程安全的STL替代品:例如,Boost库提供了线程安全的容器如`boost::container::vector`和`boost::container::map`。 理解并处理STL的线程安全问题是C++多线程编程中的重要一环,尤其在涉及到跨进程或DLL...

    vector线程中的应用

    标题"vector线程中的应用"着重讨论了在多线程环境下如何安全地使用C++标准库中的`std::vector`。`std::vector`是一个动态数组,它提供了方便的内存管理和元素访问。然而,由于其内部结构的复杂性,线程安全问题在...

    Java集合多线程安全.docx

    1. 使用`Vector`:虽然它是线程安全的,但由于每个操作都进行同步,其性能通常低于非线程安全的集合,因此不推荐在性能要求高的场景中使用。 2. 使用`Collections.synchronizedList`:这个静态方法可以将给定的`...

    dll中多线程处理vector

    在VS2010环境下开发x64平台的程序时,需要特别关注多线程安全问题,因为不正确的并发操作可能导致数据竞争和未定义行为。 首先,让我们深入理解多线程。多线程允许一个程序同时执行多个不同的任务,这样可以提高CPU...

    Java的线程安全与不安全集合.docx

    1. 使用`Vector`: 虽然`Vector`是线程安全的,但由于其全局锁定策略,效率较低,不推荐在高并发场景下使用。 2. 使用`Collections.synchronizedList(new ArrayList)`: 这种方法通过装饰器模式,将传入的`ArrayList`...

    java集合-Vector的使用

    但需要注意的是,Vector是线程安全的,在多线程环境下可以进行并发操作。如果不需要线程安全性,并且希望更高的性能,可以使用ArrayList。 需要注意的是,从Java 1.2开始,推荐使用ArrayList代替Vector,因为...

    java.util.vector中vector小结

    在Java编程语言中,`java.util.Vector`是一个重要的集合类,它是`ArrayList`的早期版本,提供了线程安全的动态数组实现。这篇文章将对`Vector`类进行详细的总结,包括其特点、用法以及与`ArrayList`的区别。 1. **...

    Java常见的线程安全的类.docx

    线程安全的集合对象,如Vector、HashTable和StringBuffer,相比于非线程安全的ArrayList、LinkedList、HashMap、HashSet、TreeMap和TreeSet、StringBuilder等,提供了额外的线程安全保障,但可能会牺牲一定的性能。...

    Java线程面试题Top50[参照].pdf

    Java 线程面试题 Top 50 Java 线程是操作系统能够进行...十、什么是线程安全? * 线程安全是指在多线程环境下,某个类或方法能够正确地工作 * Vector 是一个线程安全的类 * 线程安全是 Java 编程中非常重要的一方面

    写了一个简单的数据库连接池 与 大家交流一下,为什么使用Vector呢?

    总之,选择`Vector`可能是出于对线程安全的需求,但在现代Java编程中,考虑到性能和最佳实践,我们可能会推荐使用其他更适合的并发集合类,或者结合`Collections.synchronizedList()`等工具来手动同步`ArrayList`。...

    并发编程实践,全面介绍基础知识、JVM同步原语、线程安全、低级并发工具、线程安全容器、高级线程协作工具、Executor部分等

    本文将全面介绍Java并发编程的基础知识、JVM同步原语、线程安全、低级并发工具、线程安全容器、高级线程协作工具以及Executor服务。 1. **基础知识** - **并发与并行**:并发是指多个任务在同一时间段内交替执行,...

    socket_test.zip_多线程 vector

    在多线程环境中,向量可以用于存储从不同线程接收的数据,或者用于线程间的共享数据,但必须注意线程安全问题。为了确保数据的一致性,可能需要使用互斥锁(mutex)等同步机制来防止竞态条件。 在"socket_test"这个...

    Java理论与实践:描绘线程安全性

    接着,有条件线程安全(Conditionally Thread-Safe)的类,如`Hashtable`和`Vector`,在某些特定的、有限的使用条件下是线程安全的,但并非在所有情况下。这意味着,如果用户按照指定的方式使用,这些类可以保证线程...

    比较Vector、ArrayList和hashtable hashmap

    - Vector 和 ArrayList 都实现了 List 接口,其中 Vector 是线程安全的,而 ArrayList 不是。ArrayList 在插入和查找性能上通常优于 Vector,因为 Vector 的同步操作会带来额外的性能开销。 - LinkedList 实现了 ...

Global site tag (gtag.js) - Google Analytics