我也来说说Vector跟ArrayList的区别

这几天看到论坛首页有一个挺热的帖子[url=http://www.iteye.com/topic/924440]Vector和ArrayList的本质区别到底是什么?[/url],正好是自己正在学习的内容,所以也在这发个帖子,献献丑,如有写得不正确的,还希望各位同学斧正

帖子讨论的是面试中常见的Vector,ArrayList以及与其类似的“线程安全类”的问题

里面有几个关键点:
1.线程安全的定义
2.像Vector,HashTable这样几乎在所有方法都添加上"synchronized"能否达到线程安全的效果?(细心点的同学可能还会发现Collections.synchronizedSortedMap,Collections.synchronizedList等是用了同样的手段)
3.Vector到底有没有性能上的问题呢?

天朝人写的东西都没太大的说服力,所以尽量还是引用老外"Doug Lea"的经典《Java Concurrency in Practice》做为论述的依据

关于问题1的解释是这样的

A class is thread-safe if it behaves correctly when accessed from multiple threads, regardless of the scheduling or interleaving of the execution of those threads by the runtime environment, and with no additional synchronization or other coordination on the part of the calling code.

关于问题2呢,首先,需要知道synchronized一个方法到底是一个怎样的操作
解释是这样的:
Java provides a built-in locking mechanism for enforcing atomicity: the synchronized block. (There is also another critical aspect to locking and other synchronization mechanismsvisibilitywhich is covered in Chapter 3.) A synchronized block has two parts: a reference to an object that will serve as the lock, and a block of code to be guarded by that lock. A synchronized method is a shorthand for a synchronized block that spans an entire method body, and whose lock is the object on which the method is being invoked. (Static synchronized methods use the Class object for the lock.)


Every Java object can implicitly act as a lock for purposes of synchronization; these built-in locks are called intrinsic locks or monitor locks. The lock is automatically acquired by the executing thread before entering a synchronized block and automatically released when control exits the synchronized block, whether by the normal control path or by throwing an exception out of the block. The only way to acquire an intrinsic lock is to enter a synchronized block or method guarded by that lock.

也就是说,如果在每个方法前都加上了"synchronized",会起到这样的效果:当一个线程调用任一个该类的方法时,都要先去获取该对象的固有锁"intrinsic lock",然后才进行操作,如果当一个线程正在执行某个方法时,另一个线程也请求进入,那就需要等待前者执行完才能获得锁,然后继续执行

细心的tx想必看出来了,这样会造成严重的效率问题,比如多个线程同时执行get操作,它们根本是不可能相互影响的,但却也需要分别获得锁才能继续执行,单凭这一点就可以为问题3做一个结论了

然后再说说到底能不能达到线程安全的效果呢?
答案也是否定的

看一个例子:

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

显然,这个操作违背了上文所说的"A class is thread-safe if it behaves correctly when accessed from multiple threads"的效果

然后继续看问题3
The performance cost of synchronization comes from several sources. The visibility guarantees provided by synchronized and volatile may entail using special instructions called memory barriers that can flush or invalidate caches, flush hardware write buffers, and stall execution pipelines. Memory barriers may also have indirect performance consequences because they inhibit other compiler optimizations; most operations cannot be reordered with memory barriers.
从这段话可以看出,synchronized是会影响jvm的优化的,所以问题3的答案也很明确了:
会有性能上的问题

不过对于一些老公司,看到通篇的使用HashTable和Vector,也不必太担忧了
因为:
Modern JVMs can reduce the cost of incidental synchronization by optimizing away locking that can be proven never to contend. If a lock object is accessible only to the current thread, the JVM is permitted to optimize away a lock acquisition because there is no way another thread could synchronize on the same lock.


在这,也顺便为这本经典书打打广告,反正小弟看了是受益匪浅的,有兴趣的tx可以下载看看
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值