美文网首页Android开发Android技术知识Android开发
如何保证集合是线程安全的?ConcurrentHashMap如何

如何保证集合是线程安全的?ConcurrentHashMap如何

作者: 遛狗的程序员 | 来源:发表于2018-07-29 21:34 被阅读21次

问题:

  • 如何保证集合是线程安全的?
  • ConcurrentHashMap如何实现高效的线程安全?

知识点:

  1. 为什么需要ConcurrentHashMap?
    Hashtable比较低效,所有线程公用同一把锁,效率低下。Collections工具类提供的Map方法,大同小异,源码如下:
private static class SynchronizedMap<K, V> implements Map<K, V>, Serializable {
        private static final long serialVersionUID = 1978198479659022715L;
        private final Map<K, V> m;
        //划重点了,利用this作为互斥的mutex
        final Object mutex;
        private transient Set<K> keySet;
        private transient Set<Entry<K, V>> entrySet;
        private transient Collection<V> values;

        SynchronizedMap(Map<K, V> var1) {
            this.m = (Map)Objects.requireNonNull(var1);
            this.mutex = this;
        }

        SynchronizedMap(Map<K, V> var1, Object var2) {
            this.m = var1;
            this.mutex = var2;
        }

        public int size() {
            Object var1 = this.mutex;
         synchronized(this.mutex) {
                return this.m.size();
            }
        }

        public boolean isEmpty() {
            Object var1 = this.mutex;
           //方法不再申明为synchronized方法,但是利用this作为互斥的mutex,大同小异 synchronized(this.mutex) {
                return this.m.isEmpty();
            }
        }

高并发时候,容易始HashMap死循环导致CPU占用100%。可参考不正当使用HashMap导致cpu 100%的问题追究
HashMap 死循环的探究

  1. ConcurrentHashMap,篇幅太长,后续有专门文章分析。

回答问题

Java提供了不同层面的线程安全支持,在传统的框架内部,除了Hashtable等同步容器,还提供了所谓的同步包装器,我们可以调用Collecions工具的同步方法,来获取一个同步的包装容器(如:Collections.synchronizedMap),但是他们都是利用非常粗粒度的处理方式,在高并发的时候,性能比较低下。

另外,更加普遍的选择是利用并发包提供的线程安全容器类,它提供了:

具体保证线程安全的方式,包括从有简单的synchronize方式,到基于更加精细化的,比如基于分离锁实现的ConcurrentHashMap等并发实现等。具体选择要看开发的场景需求。总得来说,并发包提供的容器通用场景,远优于早期的简单的同步实现。
自己项目中使用代码:

private Map<Promise, ReadableMap> mPictureTakenOptions = new ConcurrentHashMap<>();
  private Map<Promise, File> mPictureTakenDirectories = new ConcurrentHashMap<>();
  
public void takePicture(ReadableMap options, final Promise promise, File cacheDirectory) {
    mPictureTakenPromises.add(promise);
    mPictureTakenOptions.put(promise, options);
    mPictureTakenDirectories.put(promise, cacheDirectory);
    if (mPlaySoundOnCapture) {
      MediaActionSound sound = new MediaActionSound();
      sound.play(MediaActionSound.SHUTTER_CLICK);
    }
    try {
      super.takePicture();
    } catch (Exception e) {
      mPictureTakenPromises.remove(promise);
      mPictureTakenOptions.remove(promise);
      mPictureTakenDirectories.remove(promise);
      throw e;
    }
  }

参考:

声明:此为原创,转载请联系作者


作者:微信公众号添加公众号-遛狗的程序员 ,或者可以扫描以下二维码关注相关技术文章。

qrcode_for_gh_1ba0785324d6_430.jpg

当然喜爱技术,乐于分享的你也可以可以添加作者微信号:

WXCD.jpeg

相关文章

网友评论

    本文标题:如何保证集合是线程安全的?ConcurrentHashMap如何

    本文链接:https://www.haomeiwen.com/subject/tsmtvftx.html