多线程与并发-----同步集合类

传统集合实现同步的问题

  举了一个例子:Map集合线程不同步导致的问题。

  解决办法:

    使用同步的Map集合 使用集合工具类中的方法将不同步的集合转为同步的Collections.synchronizedMap(new Map())这个方法返回一个同步的集合

 public static <K, V> Map<K, V> synchronizedMap(Map<K, V> m)

            {

                    return new SynchronizedMap<K, V>(m);

            }

    SynchronizedMap类相当于一个代理类,通过查看源代码发现:该类中的所有方法都是直接返回:原Map集合方法调用后的结果,只是将返回结果的代码放在了同步代码块中以实现同步,构造是将同步锁默认置为当前对象。

HashSetHashMap的关系与区别:

    1、HashSet是单列的,HashMap是双列的(键值对)关系:

    2、HashSet内部使用的是HashMap中的键,不考虑值。

  3、查看HashSet的源代码发现其内部就是用HashMap实现的,只是没有使用HashMapV,只使用了它的K

JDK1.5中提供了并发 Collection:提供了设计用于多线程上下文中的 Collection 实现:

  ConcurrentHashMapConcurrentSkipListMapConcurrentSkipListSetCopyOnWriteArrayList  CopyOnWriteArraySet。当期望许多线程访问一个给定 collection 时,ConcurrentHashMap 通常优于同步的 HashMapConcurrentSkipListMap 通常优于同步的 TreeMap。当期望的读数和遍历远远大于列表的更新数时,CopyOnWriteArrayList 优于同步的 ArrayList

        ConcurrentSkipListMap<K,V>映射可以根据键的自然顺序进行排序,也可以根据创建映射时所提供的 Comparator 进行排序,具体取决于使用的构造方法。

        ConcurrentSkipListSet<E>一个基于 ConcurrentSkipListMap 的可缩放并发 NavigableSet 实现。set 的元素可以根据它们的自然顺序进行排序,也可以根据创建 set 时所提供的 Comparator 进行排序,具体取决于使用的构造方法

        CopyOnWriteArrayList<E>ArrayList 的一个线程安全的变体,其中所有可变操作(addset 等等)都是通过对底层数组进行一次新的复制来实现的。

  这一般需要很大的开销,但是当遍历操作的数量大大超过可变操作的数量时,这种方法可能比其他替代方法 有效。在不能或不想进行同步遍历,但又需要从并发线程中排除冲突时,它也很有用。

        CopyOnWriteArraySet<E>对其所有操作使用内部 CopyOnWriteArrayList  Set。因此,它共享以下相同的基本属性:

它最适合于具有以下特征的应用程序:set 大小通常保持很小,只读操作远多于可变操作,需要在遍历期间防止线程间的冲突。 它是线程安全的。 因为通常需要复制整个基础数组,所以可变操作(addset remove 等等)的开销很大。 迭代器不支持可变 remove 操作。 使用迭代器进行遍历的速度很快,并且不会与其他线程发生冲突。在构造迭代器时,迭代器依赖于不变的数组快照。

传统集合中存在的其它问题:对集合迭代时,不能对集合中的元素进行修改(添加、删除……),Java5中提供的并发集合就解决了这个问题。

猜你喜欢

转载自blog.csdn.net/pengzhisen123/article/details/80303126