6
回答
jetty 源码问题 :AttributesMap JUC原子类的问题
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   

这是jetty9里面util包下的AttributesMap的实现

private final AtomicReference<ConcurrentMap<String, Object>> _map = new AtomicReference<>();

 ConcurrentMap 已经是 线程安全的了,为什么还要加AtomicReference 的实现呢?
加上这样的JUC原子类  会不会 多余呢?

举报
徐建海
发帖于3年前 6回/214阅
共有6个答案 最后回答: 3年前
不然的话要对使用这个MAP的方法加同步操作.
--- 共有 1 条评论 ---
徐建海非常感谢你的回答,但我还是有些疑惑,希望您看一下我下面的追问(ps:这里写不下我的追问),谢谢 3年前 回复

不是很明白,看Attributes的实例化过程

   public AttributesMap(AttributesMap attributes)
    {
        ConcurrentMap<String, Object> map = attributes.map();
        if (map != null)
            _map.set(new ConcurrentHashMap<>(map));
    }
当map为空的,会被设置成  ConcurrentHashMap,而ConcurrentHashMap 本身应该是线程安全的,毕竟内部使用了Segment[]的分段锁机制,那么使用AtomicRefecrence 做什么呢?如果 是为了线程安全的话,那么就没有必要使用Concurrent的实现机制了

引用来自“徐建海”的评论

不是很明白,看Attributes的实例化过程

   public AttributesMap(AttributesMap attributes)
    {
        ConcurrentMap<String, Object> map = attributes.map();
        if (map != null)
            _map.set(new ConcurrentHashMap<>(map));
    }
当map为空的,会被设置成  ConcurrentHashMap,而ConcurrentHashMap 本身应该是线程安全的,毕竟内部使用了Segment[]的分段锁机制,那么使用AtomicRefecrence 做什么呢?如果 是为了线程安全的话,那么就没有必要使用Concurrent的实现机制了


我大概理解错了你的原意我以为这种集合的同步问题:http://www.iteye.com/problems/88733

这里的AtomicReference强调的应该是对引用变量的原子操作而非集合读写的同步操作.关于同步我也是半吊子啊,共勉,多看并发的书了.

ConcurrentMap<String, Object> _map = new ConcurrentHashMap<>();

本来其实是上面那样,但是我又不想刚初始化就创建这个map,不用的话就浪费内存

后面问题就来了,我在运行的时候要创建这个map,是什么时候创建呢,是谁创建呢,怎么保证原子性呢,AtomicReference 出现啦

具体的代码我没有看,我猜一下

if(_map.get()==null){

ConcurrentMap<String, Object> map = new ConcurrentHashMap<>();

//set value

if(!_map.compareAndSet(null, map)){//判断有没有其他的线程在创建map对象,若有的话则合并数据,没有的话就很开心啦,直接用就可以啦

_map.get().putAll(map);

}

}





专门找了一下jetty9的源码看了一下,和我说的实现是一样的,但是方式不一样,主要的目的是为了延迟创建map并保证在并发的情况不会去创建多个map出来

下面这里就是具体的实现方式了 

 private ConcurrentMap<String, Object> ensureMap()

    {
        while (true)
        {
            ConcurrentMap<String, Object> map = map();
            if (map != null)
                return map;
            map = new ConcurrentHashMap<>();
            if (_map.compareAndSet(null, map))
                return map;
        }
    }
--- 共有 1 条评论 ---
徐建海分析的很好,这样能不能用Atomic实现单利模式呢? 作为单利模式的 懒汉模式的一种实现,相比于双重加锁和静态内部类缺省机制而言,是否更加有优势呢? 3年前 回复

引用来自“kidding”的评论

专门找了一下jetty9的源码看了一下,和我说的实现是一样的,但是方式不一样,主要的目的是为了延迟创建map并保证在并发的情况不会去创建多个map出来

下面这里就是具体的实现方式了 

 private ConcurrentMap<String, Object> ensureMap()

    {
        while (true)
        {
            ConcurrentMap<String, Object> map = map();
            if (map != null)
                return map;
            map = new ConcurrentHashMap<>();
            if (_map.compareAndSet(null, map))
                return map;
        }
    }
分析的很好,这样能不能用Atomic实现单利模式呢? 作为单利模式的 懒汉模式的一种实现,相比于双重加锁和静态内部类缺省机制而言,是否更加有优势呢?
--- 共有 1 条评论 ---
kidding锁会影响性能,这里为不是为了唯一,而是为了使用的是同一个map,比如有两个线程都new 出来map,那么我对map操作的时候,到底是操作到哪个map就有问题了,所以这里要解决的是不是唯一性,而是原子性,都操作的是一个map就ok了,多的那个丢给gc呗,这样够快,没有锁的问题,所以这里跟singleton没有多大的关系 3年前 回复
顶部