当前位置:编程学习 > JAVA >>

CopyOnWriteArrayList与Collections.synchronizedMap性能比较

机制:
 
CopyOnWriteArrayList:专为多线程并发设计的容器,“写入时复制”策略。
 
Collections.synchronizedMap:同步容器,独占策略。
 
结果:在两个线程下Collections.synchronizedMap访问时间大概是CopyOnWriteArrayList的5倍,但在64线程的时候就变成了200倍+。所以如果在容器完全只读的情况下CopyOnWriteArrayList绝对是首选。但CopyOnWriteArrayList采用“写入时复制”策略,对容器的写操作将导致的容器中基本数组的复制,性能开销较大。所以但在有写操作的情况下,CopyOnWriteArrayList性能不佳,而且如果容器容量较大的话容易造成溢出。代码中如果CopyOnWriteArrayList cl按照ArrayList al的方法初始化就会造成溢出。
 
代码如下:
 
package test;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;
 
/**
 * @author Alfred Xu <alfred.xu@heweisoft.com>
 * 
 */
public class ListPerformance {
 private final int threadNumber;
 
 public ListPerformance(int n) {
  threadNumber = n;
 }
 
 private static class TestThread implements Runnable {
  private static long totolTime;
  private final int No;
  private final int loop = 100000;
  private final Thread t;
  private final List<Integer> list;
 
  TestThread(int No, List<Integer> list) {
   this.No = No;
   this.list = list;
   t = new Thread(this);
  }
 
  public void start() {
   t.start();
  }
 
  public synchronized void addTime(long time) {
   totolTime += time;
  }
 
  @Override
  public void run() {
   long time = randomAccess();
   addTime(time);
  }
 
  @Override
  public String toString() {
   return "Thread " + No + ":";
  }
 
  public long randomAccess() {
   Date date1 = new Date();
   Random random = new Random();
   for (int i = 0; i < loop; i++) {
    int n = random.nextInt(loop);
    list.get(n);
   }
   Date date2 = new Date();
   long time = date2.getTime() - date1.getTime();
   // System.out.println(this + list.getClass().getSimpleName()
   // + " time:" + time);
   return time;
  }
 
 }
 
 public void initList(List<Integer> list, int size) {
  for (int i = 0; i < size; i++) {
   list.add(new Integer(i));
  }
 }
 
 public void test(List<Integer> list) {
  System.out.println("Test List Performance");
  TestThread[] ts = new TestThread[threadNumber];
  for (int i = 0; i < ts.length; i++) {
   ts[i] = new TestThread(i, list);
  }
  for (int i = 0; i < ts.length; i++) {
   ts[i].start();
  }
 }
 
 public static void main(String[] args) {
  ListPerformance lp = new ListPerformance(64);
  List<Integer> al = Collections
    .synchronizedList(new ArrayList<Integer>());
  lp.initList(al, 100000);
  lp.test(al);
  System.out.println(al.size());//在此处设置断点 等待创建线程完全 否则看不到效果
  System.out.println(TestThread.totolTime);
 
  TestThread.totolTime = 0;
  CopyOnWriteArrayList<Integer> cl = new CopyOnWriteArrayList<Integer>(al);
  lp.test(cl);
  System.out.println(cl.size());//在此处设置断点 等待创建线程完全 否则看不到效果
  System.out.println(TestThread.totolTime);
 }
}
补充:软件开发 , Java ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,