JDK5新特性之线程同步集合(五)

一. 传统集合:

传统方式下的Collection在迭代集合时, 不允许对集合进行修改:

public class CollectionModifyExceptionTest {

	public static void main(String[] args) {
		Collection<String> list = new ArrayList<String>();  
		list.add("aaa");
		list.add("bbb");
		list.add("ccc");
		Iterator<String> iter = list.iterator(); 
		while (iter.hasNext()) {
			String str = (String) iter.next();
			if ("aaa".equals(str)) {
				list.remove(str);
			} else {
				System.out.println(str);
			}
		}
	}
}

产生以下异常:

Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
	at java.util.AbstractList$Itr.next(AbstractList.java:343)
	at com.zdp.thread.CollectionModifyExceptionTest.main(CollectionModifyExceptionTest.java:17)

二. 同步集合:

JDK5提供了如下一些同步集合类:

ConcurrentHashMap  --> 并发条件下使用,和HashMap继承同一个类,在每个方法上都加了“锁”




CopyOnWriteArrayList  --> 可以在循环的时候进行增删操作

该集合和ArrayList最大的区别就是:做Add(E)操作的时候,容器会被copy出来一份然后再在新容器尾部添加这个元素,添加完元素之后,再将原容器

的引用指向新的容器,这样做的好处就是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以

CopyOnWrite容器也是一种读写分离思想,读和写在不同的容器


源码如下:

    /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();
            int len = elements.length;
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            newElements[len] = e;
            setArray(newElements);
            return true;
        } finally {
            lock.unlock();
        }
    }

CopyOnWrite容器适用于读多写少的并发场景。但该类也存在一些缺点:

1. 内存占用问题,因为CopyOnWrite的写时复制机制,所以在进行写操作的时候,内存里会同时驻扎两个对象的内存,旧的对象和新写入的对象


CopyOnWriteArraySet

public class CollectionModifyExceptionTest {

	public static void main(String[] args) {
		Collection<String> list = new CopyOnWriteArrayList<String>();  
		list.add("aaa");
		list.add("bbb");
		list.add("ccc");
		Iterator<String> iter = list.iterator(); 
		while (iter.hasNext()) {
			String str = (String) iter.next();
			if ("aaa".equals(str)) {
				list.remove(str);
			} else {
				System.out.println(str);
			}
		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值