首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Vector 是线程保险的

2012-08-31 
Vector 是线程安全的?Vector 是否是线程安全的?因为框架大量使用 RMI,RMI 是天生非线程安全的,所以作者认

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 处理器寄存一/二级缓存。。。

热点排行