同步容器真的是安全的吗?
来源:互联网 发布:windows窗口样式 编辑:程序博客网 时间:2024/04/30 11:53
有人认为Vector中的方法都进行了同步处理,那么一定就是线程安全的,事实上这可不一定。看下面这段代码:
public class Test { static Vector<Integer> vector = new Vector<Integer>(); public static void main(String[] args) throws InterruptedException { while(true) { for(int i=0;i<10;i++) vector.add(i); Thread thread1 = new Thread(){ public void run() { for(int i=0;i<vector.size();i++) vector.remove(i); }; }; Thread thread2 = new Thread(){ public void run() { for(int i=0;i<vector.size();i++) vector.get(i); }; }; thread1.start(); thread2.start(); while(Thread.activeCount()>10) { } } }}在我机器上运行的结果:
正如大家所看到的,这段代码报错了:数组下标越界。
也许有朋友会问:Vector是线程安全的,为什么还会报这个错?很简单,对于Vector,虽然能保证每一个时刻只能有一个线程访问它,但是不排除这种可能:
当某个线程在某个时刻执行这句时:
for(int i=0;i<vector.size();i++) vector.get(i);
假若此时vector的size方法返回的是10,i的值为9
然后另外一个线程执行了这句:
for(int i=0;i<vector.size();i++) vector.remove(i);
将下标为9的元素删除了。
那么通过get方法访问下标为9的元素肯定就会出问题了。
因此为了保证线程安全,必须在方法调用端做额外的同步措施,如下面所示:
public class Test { static Vector<Integer> vector = new Vector<Integer>(); public static void main(String[] args) throws InterruptedException { while(true) { for(int i=0;i<10;i++) vector.add(i); Thread thread1 = new Thread(){ public void run() { synchronized (Test.class) { //进行额外的同步 for(int i=0;i<vector.size();i++) vector.remove(i); } }; }; Thread thread2 = new Thread(){ public void run() { synchronized (Test.class) { for(int i=0;i<vector.size();i++) vector.get(i); } }; }; thread1.start(); thread2.start(); while(Thread.activeCount()>10) { } } }}参考:http://www.cnblogs.com/dolphin0520/p/3933404.html
0 0
- 同步容器真的是安全的吗?
- Docker 容器真的安全么?
- 是真的吗?
- 是真的吗?
- 是真的吗
- 安全函数真的安全吗?
- Docker安全性(一)——Docker容器真的安全吗?
- MD5真的安全吗?
- Java并发:线程安全的容器:同步和并发
- 真的是她吗?
- 这次是 真的吗?
- 真的是NoClassDefFoundError吗
- 预言是真的吗?
- 2012是真的吗?
- 真的是这样吗?
- 我们的wifi,真的安全吗
- 容器的线程安全
- 容器类的同步
- HDU 3037 Saving Beans (Lucas定理)
- 《Linux内核完全剖析——基于0.12内核》第3章P31 引导扇区源代码boot.s
- Oracle新建用户并指定默认表空间
- NSAttributedString UIKit Additions 参考
- 点击区域是否在某个范围内
- 同步容器真的是安全的吗?
- HDU 1272 小希的迷宫(判断一个图是否为连通图且没有环)
- Android 设置字体
- shell脚本使用ssh命令连接主机,自动创建目录,分发程序,执行命令
- 应用直接共享cookie | cookie.setPath()用法
- URI in java
- javascript根据输入的本金实时计算本息和
- java 架构师
- quartz定时任务的使用