原创文章,转载请注明出处:http://blog.csdn.net/wind5shy/article/details/5396887
平台
AMD X2 5400+,2G RAM,JDK6,eclipse 3.4
(By wind5shy:http://blog.csdn.net/wind5shy)
机制
CopyOnWriteArrayList:专为多线程并发设计的容器,“写入时复制”策略。
Collections.synchronizedMap:同步容器,独占策略。
代码:
说明:
1.在System.out.println(al.size());和System.out.println(cl.size());处需要设置断点,让main线程暂停以等待访问线程(TestThread)运行完后获得正确结果。
2.总时间中未考虑JVM线程调度等花费的时间,这些时间远小于但访问线程的访问时间,可以忽略。
结果:
线程数 | 平均访问时间 | |
| CopyOnWriteArrayList | Collections.synchronizedMap |
2 | 20 | 100 |
4 | 25 | 500 |
8 | 50 | 2200 |
16 | 120 | 8000 |
32 | 200 | 30000 |
64 | 550 | 120000 |
*程序在每个线程数设置运行10次,取每次结果的前两位为有效值计算平均值。
分析:
可以看到随着线程数不断翻倍,CopyOnWriteArrayList的访问时间基本也是翻倍,但Collections.synchronizedMap的时间则是*4。在两个线程下Collections.synchronizedMap访问时间大概是CopyOnWriteArrayList的5倍,但在64线程的时候就变成了200倍+。所以如果在容器完全只读的情况下CopyOnWriteArrayList绝对是首选。但CopyOnWriteArrayList采用“写入时复制”策略,对容器的写操作将导致的容器中基本数组的复制,性能开销较大。所以但在有写操作的情况下,CopyOnWriteArrayList性能不佳,而且如果容器容量较大的话容易造成溢出。代码中如果CopyOnWriteArrayList cl按照ArrayList al的方法初始化就会造成溢出。
(By wind5shy:http://blog.csdn.net/wind5shy)