线程安全——同步容器(五)

前言

像 ArrayList、LinkedList、HashMap 这些容器都是非线程安全的,如果有多个线程并发地访问这些容器时,就会出现问题。因此,在编写程序时,必须要求程序员手动地在任何访问到这些容器的地方进行同步处理,这样导致在使用这些容器的时候非常地不方便。

所以,Java 提供了同步容器供用户使用。

同步容器分为以下几类

  • List -> Vector,Stack
  • Map -> HashTable
  • Collections.synchronizedXXX(List、Set、Map)

同步容器的缺陷

  1. 性能问题

    锁粒度大,进行同样多的插入操作,Vector 的耗时是 ArrayList 的两倍。

    另外,由于 Vector 中的 add 方法和 get 方法都进行了同步,因此,在有多个线程进行访问时,如果多个线程都只是进行读取操作,那么每个时刻就只能有一个线程进行读取,其他线程便只能等待,这些线程必须竞争同一把锁。。

  2. 线程不是绝对安全(list集合)

    例如有两个线程,线程A根据size的值循环执行remove操作,而线程B根据size的值循环执行执行get操作。它们都需要调用size获取容器大小,当循环到最后一个元素时,若线程A先remove了线程B需要get的元素,那么就会报越界错误。

    单线程环境下的解决方法:Itr 类中给出了一个 remove()方法。但是在多线程并不适用,因为 Iterator.remove()并不是安全的。

总结

由上文可知,同步容器存在性能问题,又难做到完全的线程安全。这个时候我们就需要使用并发容器。

文章目录
  1. 1. 前言
  2. 2. 同步容器分为以下几类
  3. 3. 同步容器的缺陷
  4. 4. 总结
|