当前位置: 移动技术网 > IT编程>开发语言>Java > 详解java各种集合的线程安全

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

2019年07月19日  | 移动技术网IT编程  | 我要评论

绿箭侠第一季,spring博客,红腹水虎鱼

线程安全

首先要明白线程的工作原理,jvm有一个main memory,而每个线程有自己的working

memory,一个线程对一个variable进行操作时,都要在自己的working

memory里面建立一个copy,操作完之后再写入main

memory。多个线程同时操作同一个variable,就可能会出现不可预知的结果。根据上面的解释,很容易想出相应的scenario。

而用synchronized的关键是建立一个monitor,这个monitor可以是要修改的variable也可以其他你认为合适的object比如method,然后通过给这个monitor加锁来实现线程安全,每个线程在获得这个锁之后,要执行完load到workingmemory -> use&assign -> store到mainmemory 的过程,才会释放它得到的锁。这样就实现了所谓的线程安全。

什么是线程安全?线程安全是怎么完成的(原理)? 线程安全就是说多线程访问同一代码,不会产生不确定的结果。编写线程安全的代码是低依靠线程同步。

java相关集合

vector、arraylist、linkedlist

vector和arraylist在使用上非常相似,都可用来表示一组数量可变的对象应用的集合,并且可以随机地访问其中的元素。 

   vector的方法都是同步的(synchronized),是线程安全的(thread-safe),而arraylist的方法不是,由于线程的同步必然要影响性能,因此,arraylist的性能比vector好。  

    arraylist和linkedlist区别 

   对于处理一列数据项,java提供了两个类arraylist和linkedlist,arraylist的内部实现是基于内部数组object[],所以从概念上讲,它更象数组,但linkedlist的内部实现是基于一组连接的记录,所以,它更象一个链表结构,所以,它们在性能上有很大的差别。 

   从上面的分析可知,在arraylist的前面或中间插入数据时,你必须将其后的所有数据相应的后移,这样必然要花费较多时间,所以,当你的操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用arraylist会提供比较好的性能 

   而访问链表中的某个元素时,就必须从链表的一端开始沿着连接方向一个一个元素地去查找,直到找到所需的元素为止,所以,当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用linkedlist了。 

   如果在编程中,1,2两种情形交替出现,这时,你可以考虑使用list这样的通用接口,而不用关心具体的实现,在具体的情形下,它的性能由具体的实现来保证。   

hashtable,hashmap,hashset

hashtable和hashmap采用相同的存储机制,二者的实现基本一致,不同的是:

1)、hashmap是非线程安全的,hashtable是线程安全的,内部的方法基本都是synchronized。

2)、hashtable不允许有null值的存在。

在hashtable中调用put方法时,如果key为null,直接抛出nullpointerexception。其它细微的差别还有,比如初始化entry数组的大小等等,但基本思想和hashmap一样。

hashset:

1、hashset基于hashmap实现,无容量限制。

2、hashset是非线程安全的。

3、hashset不保证有序。

hashmap:

1、hashmap采用数组方式存储key,value构成的entry对象,无容量限制。

2、hashmap基于key hash查找entry对象存放到数组的位置,对于hash冲突采用链表的方式来解决。

3、hashmap在插入元素时可能会要扩大数组的容量,在扩大容量时须要重新计算hash,并复制对象到新的数组中。

4、hashmap是非线程安全的。

5、hashmap遍历使用的是iterator

hashtable

1、hashtable是线程安全的。

2、hashtable中无论是key,还是value都不允许为null。

3、hashtable遍历使用的是enumeration。

treeset,treemap

treeset:

1、treeset基于treemap实现,支持排序。

2、treeset是非线程安全的。

   从对hashset和treeset的描述来看,treeset和hashset一样,也是完全基于map来实现的,并且都不支持get(int)来获取指定位置的元素(需要遍历获取),另外treeset还提供了一些排序方面的支持。例如传入comparator实现、descendingset以及descendingiterator等。

treemap:

1、treemap是一个典型的基于红黑树的map实现,因此它要求一定要有key比较的方法,要么传入comparator实现,要么key对象实现comparable接口。

2、treemap是非线程安全的。

总结

以上就是本文关于详解java各种集合的线程安全的全部内容,希望对大家有所帮助。感兴趣的朋友可以参阅:java多线程forkjoinpool实例详解java线程安全与非线程安全解析java利用future及时获取多线程运行结果等,有什么问题可以随时留言,欢迎大家交流讨论。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网