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 处理器寄存一/二级缓存。。。
- 浏览: 605310 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (300)
- Web前端 (27)
- Java疑难 (60)
- 面试 (59)
- 汇编语言 (1)
- 计算机组成原理 (2)
- 操作系统 (3)
- 计算机网络 (6)
- C/C++疑难 (9)
- SSH (2)
- Web开发 (15)
- 故障 (3)
- 软件开发 (16)
- Portal开发 (1)
- 后台开发 (6)
- 数据库 (35)
- 设计模式 (4)
- 数据结构与算法 (4)
- Linux (3)
- 项目管理 (10)
- 多线程 (12)
- 嵌入式 (9)
- 网络编程 (4)
- 架构设计 (20)
- 软件工具技巧 (7)
- 并行并发 (4)
- 窗口编程 (7)
- 串口编程 (0)
- Flex (2)
- 协议 (1)
- 通讯方式 (4)
- 性能分析优化 (5)
- 测试相关 (4)
- 海量数据处理 (2)
- JAVA核心技术 (10)
- SOA (3)
- 攻略规划 (1)
- 爬虫/搜索 (2)
- 正则表达式 (1)
- A Comparison Of NoSQL Database Management Systems And Models (1)
最新评论
-
charles751:
分析的很好!但有一点:只要同步组合操作就可以了,不一定非要sy ...
Vector 是线程安全的? -
S346618898:
core Java中有一段:Vector类对自己的所有可修改方 ...
Vector 是线程安全的? -
code_cj:
基本上明白了.但执行顺是否应该是/etc/profile -& ...
profile bashrc bash_profile之间的区别和联系 -
xd2008ck:
各自有各自的场景吧楼主不要太激进了
Vector 是线程安全的? -
zwt2001267:
写的不错,赞一个
Vector 是线程安全的?
Vector 是线程安全的?
- 博客分类:
- Java疑难
评论
6 楼
charles751
2017-06-18
分析的很好!
但有一点:只要同步组合操作就可以了,不一定非要synchronzed(Vector)。
但有一点:只要同步组合操作就可以了,不一定非要synchronzed(Vector)。
5 楼
S346618898
2016-02-26
core Java中有一段:
Vector类对自己的所有可修改方法
都使用内部锁。然而,这是真的吗? Vector类的文档没有给出这样的承诺。不得不仔细研究源
代码并希望将来的版本能介绍非同步的可修改方法。如你所见,客户端锁定是非常脆弱的,通
常不推荐使用。
Vector类对自己的所有可修改方法
都使用内部锁。然而,这是真的吗? Vector类的文档没有给出这样的承诺。不得不仔细研究源
代码并希望将来的版本能介绍非同步的可修改方法。如你所见,客户端锁定是非常脆弱的,通
常不推荐使用。
4 楼
xd2008ck
2015-08-18
各自有各自的场景吧
楼主不要太激进了
楼主不要太激进了
3 楼
zwt2001267
2015-05-10
写的不错,赞一个
2 楼
primer_of_java
2014-04-29
楼主善于思考这点是很不错的. 点赞.
最近在面试的时候我遇到了让我写多线程,然后我使用了vector,果然也遇到了楼主描述的这个问题,因此不得不用同步块来完成原子操作~~
最近在面试的时候我遇到了让我写多线程,然后我使用了vector,果然也遇到了楼主描述的这个问题,因此不得不用同步块来完成原子操作~~
1 楼
fortunely
2014-04-24
分析得不错,学习了,赞一个。
那最主要的区别其实是不是就是Vector的每个函数实现都加了sychronized关键字
那最主要的区别其实是不是就是Vector的每个函数实现都加了sychronized关键字
发表评论
-
file.encoding
2015-07-23 23:43 2528参考链接 http://blog. ... -
java常用工具
2015-03-30 17:05 788jpsjstatjstackjinfojmap -
后台线程(守护线程)
2014-04-09 23:42 1421所谓的后台线程,是指在程序运行的时候在后台提供一种通用服务的 ... -
Spring配置文件xsi:schemaLocation无法解析导致启动失败的解决方案
2014-03-27 16:59 3045来源http://www.jnan.org/archives ... -
Java 内存模型
2014-01-08 10:05 696Java 内存模型 转自WIKI,自由的百科全书 跳转到 ... -
抽象类与接口选择
2013-12-06 00:20 912从设计理念层面看 abst ... -
javac和java的路径问题
2013-11-03 22:57 5751javac和java的路径问题 ... -
Java调用dll的路径问题解决
2013-10-18 00:37 2743前言:一般我们在用java写jni类库的时候,总是得把生成的 ... -
Java Ant build.xml详解
2013-07-21 23:52 9631、什么是antant是构建 ... -
Java疑难点总结
2013-06-07 02:41 11141.类加载和初始化 加载——>连接(验证-> ... -
Java 虚拟机是如何判定两个 Java 类是相同
2013-05-27 17:17 1158Java 虚拟机不仅要看类的全名是否相同,还要看加载此类的 ... -
java.lang.ClassNotFoundException和java.lang.NoClassDefFoundError的区别
2013-05-21 11:05 982这2个东西应该是java里很常见,很简单,他们都和clas ... -
深入探讨 Java 类加载器
2013-05-21 11:06 840参考 深入探讨 Java 类加载器 http://ww ... -
深入探讨 Java 类加载器
2013-05-20 15:51 814摘自http://www.ibm.com/develope ... -
深入探讨 Java 类加载器
2013-05-20 15:48 974<!--[if !mso]> <styl ... -
final变量需要显示初始化
2013-05-20 00:15 973final int f = 10;//final in ... -
try-catch-finally中return的执行情况
2013-05-18 12:04 1783public class -
Java远程通讯可选技术及原理
2013-05-13 11:13 977源自http://www.blogjava.net/Blue ... -
Java EJB、CORBA、Webservices分布式通信基本原理及特点
2013-05-13 10:19 15231. Java远程调用的特点是什么 2. Java ... -
java传参是传值还是传引用
2013-04-28 00:44 1375个人觉得java是传值,当参数类型是基本类型,复制的是值,而 ...
相关推荐
### 线程安全Vector详解 #### 一、线程安全的基本概念 在软件开发中,尤其是在并发编程领域,线程安全是一个极为重要的概念。它指的是一个类或一段代码能够被多个线程同时调用而不会导致数据不一致或其他错误的...
2. 使用线程安全的对象:使用线程安全的对象,如 Vector、Hashtable 等,而不是 ArrayList、HashMap 等。 3. 使用锁机制:使用锁机制,如 synchronized 关键字,可以锁定某个对象,以避免多个线程同时访问同一个对象...
`golang-set`库提供了一种实现,包括线程安全和非线程安全的高性能集,非常适合在Go的并发环境中使用。 首先,我们要理解什么是线程安全和非线程安全。线程安全指的是在多线程环境下,一个函数或方法在同一时刻可以...
标题"vector线程中的应用"着重讨论了在多线程环境下如何安全地使用C++标准库中的`std::vector`。`std::vector`是一个动态数组,它提供了方便的内存管理和元素访问。然而,由于其内部结构的复杂性,线程安全问题在...
5. 使用线程安全的STL替代品:例如,Boost库提供了线程安全的容器如`boost::container::vector`和`boost::container::map`。 理解并处理STL的线程安全问题是C++多线程编程中的重要一环,尤其在涉及到跨进程或DLL...
1. 使用`Vector`:虽然它是线程安全的,但由于每个操作都进行同步,其性能通常低于非线程安全的集合,因此不推荐在性能要求高的场景中使用。 2. 使用`Collections.synchronizedList`:这个静态方法可以将给定的`...
在VS2010环境下开发x64平台的程序时,需要特别关注多线程安全问题,因为不正确的并发操作可能导致数据竞争和未定义行为。 首先,让我们深入理解多线程。多线程允许一个程序同时执行多个不同的任务,这样可以提高CPU...
1. 使用`Vector`: 虽然`Vector`是线程安全的,但由于其全局锁定策略,效率较低,不推荐在高并发场景下使用。 2. 使用`Collections.synchronizedList(new ArrayList)`: 这种方法通过装饰器模式,将传入的`ArrayList`...
但需要注意的是,Vector是线程安全的,在多线程环境下可以进行并发操作。如果不需要线程安全性,并且希望更高的性能,可以使用ArrayList。 需要注意的是,从Java 1.2开始,推荐使用ArrayList代替Vector,因为...
### 当析构函数遇到多线程——C++中线程安全的对象回调 #### 1. 多线程下的对象生命期管理 C++作为一种需要程序员手动管理对象生命周期的语言,在多线程环境中,对象的创建与销毁变得更加复杂。当一个对象能够被多...
在Java编程语言中,`java.util.Vector`是一个重要的集合类,它是`ArrayList`的早期版本,提供了线程安全的动态数组实现。这篇文章将对`Vector`类进行详细的总结,包括其特点、用法以及与`ArrayList`的区别。 1. **...
线程安全的集合对象,如Vector、HashTable和StringBuffer,相比于非线程安全的ArrayList、LinkedList、HashMap、HashSet、TreeMap和TreeSet、StringBuilder等,提供了额外的线程安全保障,但可能会牺牲一定的性能。...
Java 线程面试题 Top 50 Java 线程是操作系统能够进行...十、什么是线程安全? * 线程安全是指在多线程环境下,某个类或方法能够正确地工作 * Vector 是一个线程安全的类 * 线程安全是 Java 编程中非常重要的一方面
总之,选择`Vector`可能是出于对线程安全的需求,但在现代Java编程中,考虑到性能和最佳实践,我们可能会推荐使用其他更适合的并发集合类,或者结合`Collections.synchronizedList()`等工具来手动同步`ArrayList`。...
本文将全面介绍Java并发编程的基础知识、JVM同步原语、线程安全、低级并发工具、线程安全容器、高级线程协作工具以及Executor服务。 1. **基础知识** - **并发与并行**:并发是指多个任务在同一时间段内交替执行,...
在多线程环境中,向量可以用于存储从不同线程接收的数据,或者用于线程间的共享数据,但必须注意线程安全问题。为了确保数据的一致性,可能需要使用互斥锁(mutex)等同步机制来防止竞态条件。 在"socket_test"这个...
接着,有条件线程安全(Conditionally Thread-Safe)的类,如`Hashtable`和`Vector`,在某些特定的、有限的使用条件下是线程安全的,但并非在所有情况下。这意味着,如果用户按照指定的方式使用,这些类可以保证线程...
- Vector 和 ArrayList 都实现了 List 接口,其中 Vector 是线程安全的,而 ArrayList 不是。ArrayList 在插入和查找性能上通常优于 Vector,因为 Vector 的同步操作会带来额外的性能开销。 - LinkedList 实现了 ...