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 处理器寄存一/二级缓存。。。
- 浏览: 593570 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (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 是线程安全的?
评论
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 2468参考链接 http://blog. ... -
java常用工具
2015-03-30 17:05 731jpsjstatjstackjinfojmap -
后台线程(守护线程)
2014-04-09 23:42 1384所谓的后台线程,是指在程序运行的时候在后台提供一种通用服务的 ... -
Spring配置文件xsi:schemaLocation无法解析导致启动失败的解决方案
2014-03-27 16:59 2920来源http://www.jnan.org/archives ... -
Java 内存模型
2014-01-08 10:05 653Java 内存模型 转自WIKI,自由的百科全书 跳转到 ... -
抽象类与接口选择
2013-12-06 00:20 853从设计理念层面看 abst ... -
javac和java的路径问题
2013-11-03 22:57 5702javac和java的路径问题 ... -
Java调用dll的路径问题解决
2013-10-18 00:37 2675前言:一般我们在用java写jni类库的时候,总是得把生成的 ... -
Java Ant build.xml详解
2013-07-21 23:52 9191、什么是antant是构建 ... -
Java疑难点总结
2013-06-07 02:41 10851.类加载和初始化 加载——>连接(验证-> ... -
Java 虚拟机是如何判定两个 Java 类是相同
2013-05-27 17:17 1118Java 虚拟机不仅要看类的全名是否相同,还要看加载此类的 ... -
java.lang.ClassNotFoundException和java.lang.NoClassDefFoundError的区别
2013-05-21 11:05 946这2个东西应该是java里很常见,很简单,他们都和clas ... -
深入探讨 Java 类加载器
2013-05-21 11:06 745参考 深入探讨 Java 类加载器 http://ww ... -
深入探讨 Java 类加载器
2013-05-20 15:51 788摘自http://www.ibm.com/develope ... -
深入探讨 Java 类加载器
2013-05-20 15:48 931<!--[if !mso]> <styl ... -
final变量需要显示初始化
2013-05-20 00:15 901final int f = 10;//final in ... -
try-catch-finally中return的执行情况
2013-05-18 12:04 1735public class -
Java远程通讯可选技术及原理
2013-05-13 11:13 943源自http://www.blogjava.net/Blue ... -
Java EJB、CORBA、Webservices分布式通信基本原理及特点
2013-05-13 10:19 14761. Java远程调用的特点是什么 2. Java ... -
java传参是传值还是传引用
2013-04-28 00:44 1343个人觉得java是传值,当参数类型是基本类型,复制的是值,而 ...
相关推荐
线程安全!~~涉及到vector的操作问题,以及在多线程中应该注意的事项.
关于线程安全的介绍,vector的线程安全性,vector的相关操作。线程安全性的操作.
golang-set - Go的线程安全的和非线程安全的高性能集
Java集合多线程安全 线程安全与不安全集合 线程不安全集合: ArrayList LinkedList HashMap HashSet TreeMap TreeSet StringBulider 线程安全集合: Vector HashTable Properties 集合线程安全...
但需要注意的是,Vector是线程安全的,在多线程环境下可以进行并发操作。如果不需要线程安全性,并且希望更高的性能,可以使用ArrayList。 需要注意的是,从Java 1.2开始,推荐使用ArrayList代替Vector,因为...
Java经典的List面试题目: 1、你知道的 List 都有哪些? 2 、List 和 Vector 有什么区别? 3 、List 是有序的吗?...7 、List 是线程安全的吗?如果要线程安全要怎么做? 8、怎么给 List 排序? ......
StringBuffer是线程安全的,StringBuilder不是线程安全的。 2、Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口) 答:匿名的内部类是没有名字的内部类。...
Java 最常见的 208 道面试题:第二模块答案 18. java 容器都有哪些?...30. 哪些集合类是线程安全的? 31. 迭代器 Iterator 是什么? 32. Iterator 怎么使用?有什么特点? 33. Iterator 和 ListIterator 有什么区别?
备注:对于Vector&ArrayList、Hashtable&HashMap,要记住线程安全的问题,记住Vector与Hashtable是旧的,是java一诞生就提供了的,它们是线程安全的,ArrayList与HashMap是java2时才提供的,它们是线程不安全的。...
绝对线程安全Vector的get()、remove()和size(),如果另一个线程恰好在错误的时间里删除了一个元素,导致序号i已经不再可用的话,再用i访问数组
线程安全的集合 线程安全的 List CopyOnWriteArrayList 线程安全的Set 线程安全的Map ConcurrentHashMap ConcurrentSkipListMap java集合 线程不安全的集合 HashMap的特点 HashMap在Jdk8之前使用拉链法实现,jdk8...
它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector中的方法由于添加了synchronized修饰,因此Vector是线程安全的容器,但性能上较ArrayList差,因此...
因为Vector和ArrayList除了数组扩容有点差别,还有加锁使Vector迈进了线程安全的行列外,底层实现大约是没有太大区别的!基本一致!线程安全问题更是另当别论了!继续往下看就OK! 扩容的区别: 从内部实现机制来讲...
HashMap 和 Hashtable 的区别,HashSet如何检查重复,HashMap的底层实现,HashMap 多线程操作导致死循环问题,ConcurrentHashMap 和 Hashtable 的区别,ConcurrentHashMap线程安全的具体实现⽅式/底层具体实现,...
volatile关键字的非原子性、volatile关键字的使用、AtomicInteger原子性操作、线程安全小例子:多个线程竞争问题、多个线程多个锁问题、创建一个缓存的线程池、多线程使用Vector或者HashTable的示例(简单线程同步...
47.在 java 程序中怎么保证多线程的运行安全? 48.多线程锁的升级原理是什么? 49.什么是死锁? 50.怎么防止死锁? 51.ThreadLocal 是什么?有哪些使用场景? 52.说一下 synchronized 底层实现原理? 53....
同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步的 二.数据增长:当需要增长时,Vector默认增长为原来一培,而ArrayList却是原来的一半 就HashMap与HashTable主要从三方面来说。...
30. 哪些集合类是线程安全的? 12 31. 迭代器 Iterator 是什么? 12 32. Iterator 怎么使用?有什么特点? 12 33. Iterator 和 ListIterator 有什么区别? 13 三、多线程 13 35. 并行和并发有什么区别? 13 36. 线程...
List、ArrayList、Vector及map、HashTable、HashMap的区别与用法 使用容器排序 Vector由于使用了synchronized方法(线程安全)