`
htallen
  • 浏览: 17965 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

线程安全的集合

阅读更多

转载自:http://mahuangyihao.iteye.com/blog/181156
Java代码

   1. 线程安全的集合包含2个问题  
   2. 1.多线程并发修改一 个 集合 怎么办?  
   3. 2.如果迭代的过程中 集合 被修改了怎么办?  
   4.     a.一个线程在迭代,另一个线程在修改  
   5.     b.在同一个线程内用同一个迭代器对象进行迭代、修改、迭代、修改. . .  
   6.   
   7.    
   8.   
   9. 共有有3种解决方案  
  10. 1.用老的Vector/Hashtable类,上面2个问题都不用担心。  
  11. Vector/Hashtable所提供的所有方法都是 synchronized的。如果 迭代的过程中数据结构被修改了,迭代器可以反映最新的修改,也不会抛异常。但这种方法效率低下,不建议使用。  
  12.   
  13.    
  14.   
  15. 2.使用ArrayList/HashMap和同步包装器  
  16.   
  17. 可用 同步包装器使容器变成线程安全的  
  18. Java代码  
  19.   
  20.    1. List synchArrayList = Collections.synchronizedList(new ArrayList());<br>    
  21.    2. Map synchHashMap = Collections.synchronizedMap(new HashMap())<br>    
  22.   
  23. List synchArrayList = Collections.synchronizedList(new ArrayList());  
  24.   
  25. Map synchHashMap = Collections.synchronizedMap(new HashMap())  
  26.   
  27. 如果要迭代,需要这样  
  28. Java代码  
  29.   
  30.    1. synchronized (synchHashMap)<br>    
  31.    2. {<br>    
  32.    3.    Iterator iter = synchHashMap.keySet().iterator();<br>    
  33.    4.    while (iter.hasNext()) . . .;<br>    
  34.    5. }<br>    
  35.   
  36. synchronized (synchHashMap)  
  37.   
  38. {  
  39.   
  40.    Iterator iter = synchHashMap.keySet().iterator();  
  41.   
  42.    while (iter.hasNext()) . . .;  
  43.   
  44. }  
  45.   
  46.   
  47.    
  48.   
  49. 注意上面的代码每次进入同步块都生成了一个新的迭代器。如果你还用老的迭代器,2b的情况就可能发生,你会收到一个ConcurrentModificationException。  
  50.   
  51.    
  52.   
  53. 3.用java5.0新加入的ConcurrentLinkedQueue、ConcurrentHashMap、CopyOnWriteArrayList 和 CopyOnWriteArraySet  
  54. 对这些集合进行并发修改是安全的。  
  55. 针对2b的问题,迭代器既不抛异常,也不会反映新的修改。就是说你迭代的是生成迭代器时的容器,不是最新的容器。  

线程安全的集合包含2个问题
1.多线程并发修改一 个 集合 怎么办?
2.如果迭代的过程中 集合 被修改了怎么办?
    a.一个线程在迭代,另一个线程在修改
    b.在同一个线程内用同一个迭代器对象进行迭代、修改、迭代、修改. . .

 

共有有3种解决方案
1.用老的Vector/Hashtable类,上面2个问题都不用担心。
Vector/Hashtable所提供的所有方法都是 synchronized的。如果 迭代的过程中数据结构被修改了,迭代器可以反映最新的修改,也不会抛异常。但这种方法效率低下,不建议使用。

 

2.使用ArrayList/HashMap和同步包装器

可用 同步包装器使容器变成线程安全的
Java代码

   1. List synchArrayList = Collections.synchronizedList(new ArrayList());<br>  
   2. Map synchHashMap = Collections.synchronizedMap(new HashMap())<br>  

List synchArrayList = Collections.synchronizedList(new ArrayList());

Map synchHashMap = Collections.synchronizedMap(new HashMap())

如果要迭代,需要这样
Java代码

   1. synchronized (synchHashMap)<br>  
   2. {<br>  
   3.    Iterator iter = synchHashMap.keySet().iterator();<br>  
   4.    while (iter.hasNext()) . . .;<br>  
   5. }<br>  

synchronized (synchHashMap)

{

   Iterator iter = synchHashMap.keySet().iterator();

   while (iter.hasNext()) . . .;

}


 

注意上面的代码每次进入同步块都生成了一个新的迭代器。如果你还用老的迭代器,2b的情况就可能发生,你会收到一个ConcurrentModificationException。

 

3.用java5.0新加入的ConcurrentLinkedQueue、ConcurrentHashMap、CopyOnWriteArrayList 和 CopyOnWriteArraySet
对这些集合进行并发修改是安全的。
针对2b的问题,迭代器既不抛异常,也不会反映新的修改。就是说你迭代的是生成迭代器时的容器,不是最新的容器。


 

分析(20090414追加):

 

方案1:Vector和HashTable都是线程安全的。

 

方案2:返回的都是经过封装(线程安全的)的list和map。

->将指定的list和map传进去,传出来的是经过线程安全处理的list和map。(20090507追加)
static
<T> List <T>
    synchronizedList (List <T> list)
          Returns a synchronized (thread-safe) list backed by the specified list.
static
<K,V> Map <K,V>
    synchronizedMap (Map <K,V> m)
          Returns a synchronized (thread-safe) map backed by the specified map.

 

方案3:这几个类都是位于java.util.concurrent 包中。(concurrent:并发的, 协作的, 一致的。也就是同步的意思。 )

①java.util.concurrent 包中的Class ConcurrentLinkedQueue<E>:An unbounded thread-safe queue based on linked nodes.(无界线程安全队列基于联系节点。)

②java.util.concurrent 包中的Class ConcurrentHashMap<K,V>:A hash table supporting full concurrency of retrievals and adjustable expected concurrency for updates.(哈希表的全面支持并发检索和可调预计并发更新。)

③java.util.concurrent 包中的Class CopyOnWriteArrayList<E>:A thread-safe variant of ArrayList in which all mutative operations (add, set, and so on) are implemented by making a fresh copy of the underlying array.(线程安全的变体的ArrayList中,所有变化的行动(购买,设置,等等)的实施作出了新的副本的基本元素。)

④java.util.concurrent 包中的Class CopyOnWriteArraySet<E>:A Set that uses CopyOnWriteArrayList for all of its operations.(一组使用CopyOnWriteArrayList其所有的业务。)

 
分享到:
评论

相关推荐

    Java多线程安全集合

    在Java编程中,多线程安全集合是程序员在并发环境下处理数据共享时必须考虑的关键概念。这些集合确保了在多个线程访问时的数据一致性、完整性和安全性,避免了竞态条件、死锁和其他并发问题。Java提供了一系列的线程...

    c#官方线程安全集合源码

    在.NET框架中,C#提供了一系列的线程安全集合类,这些类被设计为在多线程环境下可以安全地进行数据操作。这些类是通过`System.Collections.Concurrent`命名空间提供的,确保了在并发访问时的数据一致性。让我们深入...

    .NET Framework4 线程安全集合详解

    - **概述**:BlockingCollection&lt;T&gt; 是一个高级的线程安全集合,实现了 `IProducerConsumerCollection&lt;T&gt;` 接口。它提供了线程间的生产者-消费者模式,支持添加和移除操作的阻塞,可以限制集合的大小,避免资源过度...

    jdk中线程安全的集合类.docx

    综上所述,`ConcurrentHashMap`和`ConcurrentSkipListMap`都是为了解决多线程环境下的并发问题而设计的高效线程安全集合类。`ConcurrentHashMap`通过分段锁和细粒度锁的机制提高了并发性能,而`...

    Java的线程安全与不安全集合.docx

    线程安全集合: 1. `Vector`: 类似于`ArrayList`,但它在每个操作上都添加了`synchronized`关键字,使其成为线程安全的。然而,由于它的同步机制过于简单,性能通常较低。 2. `HashTable`: 类似于`HashMap`,但...

    ArrayList的线程安全测试

    在C#中,如果要在多线程中使用ArrayList,必须采取适当的同步措施,例如使用`lock`关键字、Monitor类或者`System.Collections.Concurrent`命名空间中的线程安全集合。 首先,让我们了解ArrayList的基本操作。...

    线程安全集合类Concurrent测试

    Task task = BlockingCollectionUtil.AddTakeBlockingCollectionAsync(); Task.WaitAny(task); BlockingCollectionUtil.TryTakeBlockingCollection(); ConcurrentBagUtil.Test(); ConcurrentDictionaryUtil....

    C#线程安全的事件类研究报告

    一种常见的线程安全事件实现是使用`ConcurrentQueue&lt;T&gt;`或`ConcurrentStack&lt;T&gt;`这样的线程安全集合来管理事件处理程序。这些集合在内部已经实现了线程安全,可以确保在添加和移除元素时不会发生冲突。例如,你可以...

    Java集合多线程安全.docx

    然而,并非所有集合类都是线程安全的,这在多线程环境中可能导致数据不一致或者运行时异常。线程安全指的是一个对象在多线程环境下可以被正确地访问和修改,而不会出现竞态条件或死锁等问题。 线程不安全的集合类...

    非死锁读/写储物柜和线程安全集合

    标题 "非死锁读/写储物柜和线程安全集合" 涉及到的是在多线程编程中如何避免死锁问题以及实现线程安全的数据结构。死锁是多线程环境下的一种常见问题,当两个或多个线程相互等待对方释放资源,导致它们都无法继续...

    C#多线程List的非线程安全性

    2. 使用线程安全的集合:.NET框架提供了线程安全的集合类,如ConcurrentBag、ConcurrentQueue和ConcurrentStack等,它们在内部实现了线程同步,可以安全地在多线程环境下使用。 3. 避免在多线程环境中直接修改List...

    线程安全在Java中的应用与实践.pptx.pptx

    - **线程安全集合类**:如Vector、Hashtable和ConcurrentHashMap,它们在内部实现了同步,可以在多线程环境中安全使用,避免数据一致性问题。 - **非线程安全集合类**:如ArrayList、HashMap等,需要程序员自己...

    java集合类线程安全.doc

    Java 集合类线程安全 Java 集合框架是由 Java 平台标准版 1.2 引入的通用数据结构与算法框架。其灵活的面对对象设计受到了广大 Java 程序员的一致青睐,为 Java 平台的成熟奠定了坚实的基础。 线程安全不是一个...

    多线程中使用Java集合类.doc

    2. 使用`java.util.concurrent`包下的线程安全集合类:如CopyOnWriteArrayList和CopyOnWriteArraySet。这些类在内部实现上保证了线程安全,它们通过复制原集合创建新集合来避免修改时的并发问题。这种方式适用于迭代...

    详解java各种集合的线程安全

    Java 集合的线程安全详解 Java 集合的线程安全是指在多线程环境中,集合操作的安全性。 Java 中有多种集合类,如 Vector、ArrayList、LinkedList、HashTable、HashMap、HashSet 等,这些集合类在多线程环境中的安全...

    java线程安全总结.pdf

    7. **线程安全集合** - `java.util.concurrent` 包中的集合类,如`ConcurrentHashMap`、`CopyOnWriteArrayList`等,设计时就考虑了线程安全,避免了在多线程环境下的同步问题。 8. **线程优先级与调度** - Java...

    关于如何解决HashMap线程安全问题的介绍

    但是需要注意,虽然这个方法可以保证基本的线程安全,但迭代仍然是非线程安全的,即不能在遍历过程中修改Map。 2. 使用ConcurrentHashMap:Java从1.5版本开始引入了ConcurrentHashMap,它是线程安全且高并发性能的...

    C# 多线程资料集合

    本资源集合提供了一套全面的C#多线程学习资料,包括编程实例实战、线程技术详解以及多线程相关概念的阐述,特别适合于想要深入理解和掌握C#线程编程的开发者。 首先,C#中的线程允许程序员同时执行多个任务,这被...

    java 多线程同步

    高级实用工具类是`java.util.concurrent`的核心,包括线程安全集合(如ConcurrentHashMap、CopyOnWriteArrayList等)、线程池(ExecutorService、ThreadPoolExecutor、ScheduledThreadPoolExecutor等)、信号...

Global site tag (gtag.js) - Google Analytics