Java 并发数据结构

并发数据结构

  • 常用的数据结构是线程不安全的
    – ArrayList,HashMap,HashSet 非同步的
    – 多个线程同时读写这些数据结构时,可能会抛出异常或者数据错误
  • 传统的Vector,Hashtable等同步的集合性能过差
  • 并发的数据结构:数据添加或者删除
    – 阻塞式集合:当集合为空或者满时,等待
    – 非阻塞式集合:放集合为空或者满时,不等待,返回null或异常
List
  • Vector 同步安全,写多读少
  • ArrayList 不安全
  • Collections.synchronizedList(List list)这个方法,将线程不安全的变成线程安全的, 基于synchronized(所包围的代码一次只能一个线程进入),效率差
  • JAVA 5开始,提供CopyOnWriteArrayList 这个类,读多写少,基于复制机制的一个并发链表类,是非阻塞
Set
  • HashSet 不安全
  • Collections.synchronizedSet(Set set)方法,将线程不安全变成线程安全的,基于synchronized,效率差
  • CopyOnWriteArraySet(基于CopyOnWriteArrayList),读多写少,非阻塞,线程安全的
Map
  • Hashtable 同步安全,写多读少,性能不太行
  • HashMap 不安全
  • Collections.synchronizedMap(Map map)方法,基于synchronized,效率差
  • ConcurrentHashMap ,读多写少,非阻塞,线程安全
Queue/Deque(队列,jdk1.5)
  • ConcurrentLinkedQueue 非阻塞
  • ArrayBlockingQueue/LinkedBlockingQueue 阻塞

用三种方法创建三个list,三个list传入三个线程类对象,每一个线程类对象创建十个线程,线程run方法是向list插入十个数,这样 每个list中就有100个数字。发现ArrayList创建的list中,数字的插入发生错误,线程不安全,其他俩种都是正确的。
其他的数据结构也类似

public class ListTest {    
 
    public static void main(String[] args) throws InterruptedException{

        //线程不安全
        List<String> unsafeList = new ArrayList<String>();
        //线程安全
        List<String> safeList1 = Collections.synchronizedList(new ArrayList<String>());
        //线程安全
        CopyOnWriteArrayList<String> safeList2 = new CopyOnWriteArrayList<String>();

        ListThread t1 = new ListThread(unsafeList);
        ListThread t2 = new ListThread(safeList1);
        ListThread t3 = new ListThread(safeList2);

        for(int i = 0; i < 10; i++){
            Thread t = new Thread(t1, String.valueOf(i));
            t.start();
        }
        for(int i = 0; i < 10; i++) {
            Thread t = new Thread(t2, String.valueOf(i));
            t.start();
        }
        for(int i = 0; i < 10; i++) {
            Thread t = new Thread(t3, String.valueOf(i));
            t.start();
        }

        //等待子线程执行完
        Thread.sleep(2000);
 
        System.out.println("listThread1.list.size() = " + t1.list.size());
        System.out.println("listThread2.list.size() = " + t2.list.size());
        System.out.println("listThread3.list.size() = " + t3.list.size());

        //输出list中的值
        System.out.println("unsafeList:");
        for(String s : t1.list){
            if(s == null){
            	System.out.print("null  ");
            }
            else
            {
            	System.out.print(s + "  ");
            }
        }
        System.out.println();
        System.out.println("safeList1:");
        for(String s : t2.list){
        	if(s == null){
            	System.out.print("null  ");
            }
            else
            {
            	System.out.print(s + "  ");
            }
        }
        System.out.println();
        System.out.println("safeList2:");
        for(String s : t3.list){
        	if(s == null){
            	System.out.print("null  ");
            }
            else
            {
            	System.out.print(s + "  ");
            }
        }
    }
}

class ListThread implements Runnable{  //线程类,向list添加元素
	public List<String> list;

    public ListThread(List<String> list){
        this.list = list;
    }

    @Override
    public void run() {
    	int i = 0;
    	while(i<10)
    	{
    		try {
                Thread.sleep(10);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            //把当前线程名称加入list中
            list.add(Thread.currentThread().getName());
            i++;
    	}        
    }
}

//输出
listThread1.list.size() = 87
listThread2.list.size() = 100
listThread3.list.size() = 100
unsafeList:
null  null  1  0  9  8  7  6  5  4  null  null  null  0  5  null  null  null  6  8  2  0  null  ......
safeList1:
8  7  9  6  5  4  3  2  1  0  0  1  2  4  3  5  6  7  8  9  9  8  7  6  5  3  4  2  1  0  0  9  ...... 
safeList2:
0  6  7  8  4  1  3  5  2  9  0  2  6  5  1  3  9  8  7  4  0  7  8  3  2  9  6  5  4  1  0  5  ....
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值