Java中各种集合(字符串类)的线程安全性!!!
Java中各种集合(字符串类)的线程安全性!!!
⼀、概念:
线程安全:就是当多线程访问时,采⽤了加锁的机制;即当⼀个线程访问该类的某个数据时,会对这个数据进⾏保护,其他线程不能对其访问,直到该线程读取完之后,其他线程才可以使⽤。防⽌出现数据不⼀致或者数据被污染的情况。
线程不安全:就是不提供数据访问时的数据保护,多个线程能够同时操作某个数据,从⽽出现数据不⼀致或者数据污染的情况。
对于线程不安全的问题,⼀般会使⽤synchronized关键字加锁同步控制。
线程安全⼯作原理: jvm中有⼀个main memory对象,每⼀个线程也有⾃⼰的working memory,⼀个线程对于⼀个变量variable进⾏操作的时候,都需要在⾃⼰的working memory⾥创建⼀个copy,操作完之后再写⼊main memory。
当多个线程操作同⼀个变量variable,就可能出现不可预知的结果。
⽽⽤synchronized的关键是建⽴⼀个监控monitor,这个monitor可以是要修改的变量,也可以是其他⾃⼰认为合适的对象(⽅法),然后通过给这个monitor加锁来实现线程安全,每个线程在获得这个锁之后,要执⾏完加载load到working memory 到 use && 指派assign 到存储store 再到 main memory的过程。才会释放它得到的锁。这样就实现了所谓的线程安全。
⼆、线程安全(Thread-safe)的集合对象:
Vector
HashTable
StringBuffer
三、⾮线程安全的集合对象:
ArrayList :
LinkedList:
HashMap:
HashSet:
TreeMap:
TreeSet:
StringBulider:
四、相关集合对象⽐较:
Vector、ArrayList、LinkedList:
1、Vector:
Vector与ArrayList⼀样,也是通过数组实现的,不同的是它⽀持线程的同步,即某⼀时刻只有⼀个线程能够写Vector,避免多线程同时写⽽引起的不⼀致性,但实现同步需要很⾼的花费,因此,访问它⽐访问ArrayList慢。
2、ArrayList:
a. 当操作是在⼀列数据的后⾯添加数据⽽不是在前⾯或者中间,并需要随机地访问其中的元素时,使⽤
ArrayList性能⽐较好。
b. ArrayList是最常⽤的List实现类,内部是通过数组实现的,它允许对元素进⾏快速随机访问。数组的缺点是每个元素之间不能有间
隔,当数组⼤⼩不满⾜时需要增加存储能⼒,就要讲已经有数组的数据复制到新的存储空间中。当从ArrayList的中间位置插⼊或者删除元素时,需要对数组进⾏复制、移动、代价⽐较⾼。因此,它适合随机查和遍历,不适合插⼊和删除。
3、LinkedList:
a. 当对⼀列数据的前⾯或者中间执⾏添加或者删除操作时,并且按照顺序访问其中的元素时,要使⽤LinkedList。
b. LinkedList是⽤链表结构存储数据的,很适合数据的动态插⼊和删除,随机访问和遍历速度⽐较慢。另外,他还提供了List接⼝中没
有定义的⽅法,专门⽤于操作表头和表尾元素,可以当作堆栈、队列和双向队列使⽤。
    Vector和ArrayList在使⽤上⾮常相似,都可以⽤来表⽰⼀组数量可变的对象应⽤的集合,并且可以随机的访问其中的元素。
HashTable、HashMap、HashSet:
HashTable和HashMap采⽤的存储机制是⼀样的,不同的是:
1、HashMap:
a. 采⽤数组⽅式存储key-value构成的Entry对象,⽆容量限制;
b. 基于key hash查Entry对象存放到数组的位置,对于hash冲突采⽤链表的⽅式去解决;
c. 在插⼊元素时,可能会扩⼤数组的容量,在扩⼤容量时须要重新计算hash,并复制对象到新的数组中;
d. 是⾮线程安全的;
e. 遍历使⽤的是Iterator迭代器;
2、HashTable:
a. 是线程安全的;
b. ⽆论是key还是value都不允许有null值的存在;在HashTable中调⽤Put⽅法时,如果key为null,直接抛出NullPointerException异
常;
c. 遍历使⽤的是Enumeration列举;
3、HashSet:
a. 基于HashMap实现,⽆容量限制;
b. 是⾮线程安全的;
c. 不保证数据的有序;
TreeSet、TreeMap:
TreeSet和TreeMap都是完全基于Map来实现的,并且都不⽀持get(index)来获取指定位置的元素,需要遍历来获取。另外,TreeSet还提供了⼀些排序⽅⾯的⽀持,例如传⼊Comparator实现、descendingSet以及descendingIterator等。
1、TreeSet:
a. 基于TreeMap实现的,⽀持排序;
b. 是⾮线程安全的;
2、TreeMap:
a. 典型的基于红⿊树的Map实现,因此它要求⼀定要有key⽐较的⽅法,要么传⼊Comparator⽐较器实现,要么key对象实现
Comparator接⼝;
b. 是⾮线程安全的;
StringBuffer和StringBulider:
StringBuilder与StringBuffer都继承⾃AbstractStringBuilder类,在AbstractStringBuilder中也是使⽤字符数组保存字符串。
    1、在执⾏速度⽅⾯的⽐较:StringBuilder > StringBuffer ;
    2、他们都是字符串变量,是可改变的对象,每当我们⽤它们对字符串做操作时,实际上是在⼀个对象上操作的,不像String⼀样创建⼀些对象进⾏操作,所以速度快;
  3、 StringBuilder:线程⾮安全的;
    4、StringBuffer:线程安全的;
  对于String、StringBuffer和StringBulider三者使⽤的总结:
  1.如果要操作少量的数据⽤ = String字符串截取不改变原字符串
  2.单线程操作字符串缓冲区下操作⼤量数据 = StringBuilder
  3.多线程操作字符串缓冲区下操作⼤量数据 = StringBuffer

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。