并发线程集深入浅出

安全集合
Vector、Hashtable 他们是使用了synchronized修饰方法来保证线程的安全,缺点就是效率低
非线程安全的集合
比较主流的有ArrayList、HashMap线程不安全但是效率高,用来替代Vector、Hashtable集合 主要使用场景是对线程安全要求不高的时候,如果想线程安全需要使用:Collections.synchronizedList(list)、Collections.synchronizedMap(map)底层使用了synchronized代码块 虽然也是锁住了代码但是锁的是代码里边,并非方法外边,可以理解为性能稍微有点提升吧,毕竟方法本身就是要分配资源的
在大量并发的情况下如何提升集合?
采用java.util.concurrent.*包中的方法,ConcurrentHashMap 用来提升map的效率CopyOnWriteArrayList 用来提升List的效率CopyOnWriteArraySet 用来提升Set效率他们的底层采用的是Lock锁,保证安全的同时,性能也很高

  1. ConcurrentHashMap:分段(segment)锁定+Lock锁是线程安全的HashMap,并且性能不Hashtable、synchronizedMap都有提升他的底层使用的并不是Synchronized代码块锁,也不是synchronzied方法锁并且底层使用了分离的技术,使用多个锁来控制对hash表的不同部分,进行修改的,采用了ReentrantLock锁来实现如果多个修改操作不在相同的段上,他们就可以并发进行,从而提升了效率但是JDK1.7和JDK1.8实现差异较大,以上的理论都属于JDK1.7JDK1.8对ConcurrentHashMap进行了巨大的改动,他撅弃了分段锁的概念,启用了一种全新的方法实现,利用了CAS算法 他的底层是由“数组+链表+红黑树”的方式实现的为了做到并发,有增加了很多辅助类,列如TreeBin,Traverser等对象内部类。
  2. CopyOnWriteArrayList:CopyOnWrite(复制写)+Lock锁对于set(),add(),remove()等方法使用ReentrantLock的lock和unLock来加锁和解锁读 操作不需要加锁,(之前安全的集合类为了保证线程同步,连查询都加锁)对于CopyOnWrite原理:写时复制通俗的讲就是我们在往一个容器中添加元素的时候,不直接往当前容器中添加,而是先将当前容器进行copy,复制出一个新的容器,然后往新的容器中添加元素,添加完元素之后,再将原容器的引用指向新的容器,这样做的好处是可以对copyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素,所以CopyOnWrite容器也是读写分离的一种思想,读和写不同的容器,对于读操作远远多于写操作的应用非常适合再并发的情况下提高性能的并发读取CopyOnWrite容器只能保证数据最终的一致性,不能保证数据实时的一致性,所以如果希望写入的数据马上能读到,请不要使用CopyOnWrite容器
  3. CopyOnWriteArraySet:copyOnWrite+Lock锁它是线程安全的无序的集合,可以将它理解为线程安全的HashSet有意思的是,CopyOnWriteArraySet和HashSet虽然都是继承于共同的父类AbstractSet但是HashSet是通过 散列表(HashMap)实现的,而CopyOnWriteArraySet则是通过 动态数组(CopyOnWriteArrayList)来实现的,并不是散列表CopyOnWriteArraySet和CopyOnWriteArrayList的基础上使用了Java的修饰模式,所以底层是相同的,而CopyOnWriteArrayList本质是个动态数组队列,所以CopyOnWriteArraySet相当于通过动态散数组实现的集合,CopyOnWriteArrayList中允许有重复的元素,但是,CopyOnWriteArraySet是一个集合,他不允许有重复的集合,因此CopyOnWriteArrayList额外提供了addIfAbsent()和AddAllAbsent()这两个来添加元素的API,通过这两个API添加元素的时候只有当元素不存在的时候才添加

测试代码

public class TestConcurrentContainer {
    
        public static void main(String[] args) {

            //第一代  同步方法  效率太低  查询也要加锁
            Vector v;
            Hashtable ht;

            //第二代 效率高  线程不安全
            ArrayList list;
            HashMap map;

            //安全第一  在多线程情况下,怎么办?
//        Collections.synchronizedList();
//        Collections.synchronizedCollection();
//        Collections.synchronizedMap();
//        Collections.synchronizedSet();
            List list2 = new ArrayList();
            Collections.addAll(list2,10,40,30,50,40);
            System.out.println(list2);
            //采用了同步代码块,效率比同步方法要高
            list2 = Collections.synchronizedList(list2);
            //list2 =  new Collections.SynchronizedRandomAccessList<>(list1);

            //第三代的并发集合类  Lock锁+其他提升性能的技术  安全+性能高
            //List
            List list3 = new CopyOnWriteArrayList();
            //Set  底层是CopyOnWriteArrayList
            CopyOnWriteArraySet set = new CopyOnWriteArraySet();
            set.add("HTML");
            set.add("HTML");
            set.add("HTML");
            System.out.println(set.size());

        /*

         public boolean addIfAbsent(E e) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            // Copy while checking if already present.
            // This wins in the most common case where it is not present
            Object[] elements = getArray();
            int len = elements.length;
            Object[] newElements = new Object[len + 1];
            for (int i = 0; i < len; ++i) {
                if (eq(e, elements[i]))
                    return false; // exit, throwing away copy
                else
                    newElements[i] = elements[i];
            }
            newElements[len] = e;
            setArray(newElements);
            return true;
        } finally {
            lock.unlock();
        }
    }

         */
            //Map
            Map<String,String> chmap = new ConcurrentHashMap<String,String>();

            //功能强大的并发包   多线程开发  并发集合
            Callable callable;
            Lock lock = new ReentrantLock();//Re-entrant-Lock 可重入的锁
            Future future;
            ExecutorService pool = Executors.newFixedThreadPool(10);

            //List  不唯一  有序(索引顺序)
            //Set   唯一    HashSet 无序  LinkedHashSet 有序 索引顺序  TreeSet 自然顺序
            //CopyOnWriteArrayList         不唯一  有序(索引顺序)
            // CopyOnWriteArraySet  能保证唯一性  添加的时候判断一下,存在就不添加了。不就唯一了
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值