多线程之同步类容器和并发类容器ConcurrentMap,CopyOnWrite讲解

同步类容器

同步类容器都是线程安全的,但是在有时候需要加锁来保护复合操作,比如:迭代(反复访问容器中的元素),跳转(根据指定顺序找到当前元素的下一个),条件运算,有时候并发操作,可能会引起意外。比如ConcurrentModificationException异常(迭代集合元素时候,并发修改)。

同步类容器有:vector HashTable,底层都是采用synchronized进行同步的。
注意可以采用如下方式使得容器同步:

Map<String,String > map=Collections.synchronizedMap(new HashMap<String,String>());

ConcurrentMap

同步类容器虽然线程安全,但是他们的状态都是串行化,严重降低了性能。
而并发类容器则是专门针对并发设计的使用ConcurrentMap代替传统的hashTable,使用CopyOnWriteArrayList代替了传统的vector,还有并发的CopyOnWriteArraySet,以及并发的Queue,ConcurrentLinkedQueue(高性能队列),LinkedBlockingQueue(阻塞队列)。

ConcurrentMap接口有如下两个重要实现:
ConcurrentHashMap和ConcurrentSkipListMap(支持并发排序功能)

支持并发的原理:ConcurrentHashMap内部采用段来表示这些不同的部分,每个段实际上就是一个HashMap,他们有自己的锁,只要不同的操作发生在不同的段上,就可以并发执行,一共把一个整体分成了16段,也就是说最高支持16个线程并发操作容器,这是一种通过减小锁粒度的办法来降低锁的竞争的方案,并且代码中大多共享变量使用volatile关键字声明,目的是第一时间获取修改内容,性能非常好。

package com.wuk.thread;

import java.util.concurrent.ConcurrentHashMap;

public class MyThread04 {

    private static ConcurrentHashMap<String, String> chMap=new ConcurrentHashMap<String, String>();
    public static void main(String[] args) {

        chMap.put("k1", "v1");
        chMap.put("k2", "v2");
        chMap.put("k3", "v3");
        chMap.put("k4", "v4");
        chMap.put("k5", "v5");
        chMap.putIfAbsent("k1", "1111");//如果存在不插入

    }

}

CopyOnWrite

简称COW,COW容器有两种:CopyOnWriteArrayList和CopyOnWriteArraySet。

CopyOnWrite的理解:
CopyOnWrite容器也就是写时复制的容器,即当我们往一个容器中添加元素时候,不直接往当前容器添加,而是先将当前容器进行复制,然后往新的容器里添加元素,添加之后,将原容器的引用指向新的容器,这样的好处是我们可以对CopyOnWrite容器进行并发的读写操作,而不需要加任何锁,这就是一种读写分离的容器。

但是记住这种适合于读多写少的场合,因为复制一个容器比较浪费资源和时间。

注意如果出现多个线程写的情况下,就会采用等待的方式,看看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();
        }
    }

ReentrantLock 重入锁
lock.lock();加锁
lock.unlock(); 释放锁

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术闲聊DD

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值