zoukankan      html  css  js  c++  java
  • java各种集合的线程安全

    java各种集合的线程安全

    1. 什么是线程安全?

      想要搞清楚这个问题,首先要明白线程的工作原理: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的过程,才会释放它得到的锁。这样就实现了所谓的线程安全。

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

    2. java相关集合

     2.1 Vector、ArrayList、LinkedList

      Vector和ArrayList的区别

      Vector和ArrayList在使用上非常相似,都可用来表示一组数量可变的对象应用的集合,并且可以随机地访问其中的元素。Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。  

      ArrayList和LinkedList区别

      对于处理一列数据项,Java提供了两个类ArrayList和LinkedList,ArrayList的内部实现是基于内部数组Object[],所以从概念上讲,它更象数组,但LinkedList的内部实现是基于一组连接的记录,所以,它更象一个链表结构,所以,它们在性能上有很大的差别。从上面的分析可知,在ArrayList的前面或中间插入数据时,你必须将其后的所有数据相应的后移,这样必然要花费较多时间,所以,当你的操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能。而访问链表中的某个元素时,就必须从链表的一端开始沿着连接方向一个一个元素地去查找,直到找到所需的元素为止,所以,当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。如果在编程中,1,2两种情形交替出现,这时,你可以考虑使用List这样的通用接口,而不用关心具体的实现,在具体的情形下,它的性能由具体的实现来保证。

     2.2 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。
  • 相关阅读:
    URL编码及解码
    Javascript解析URL
    为什么在JavaScript中0.1+0.2不等于0.3?
    void 0 与 undefined
    Windows7、Windows10下把Git Bash Here 添加到右键菜单(ContextMenu)
    [菜鸟]C++创建类对象时(无参)后不加括号与加括号的区别
    git常用命令
    git 出错及解决
    Vim升华之树形目录插件NERDTree安装图解
    rails.vim环境安装(ubuntu)
  • 原文地址:https://www.cnblogs.com/chen-kh/p/6397693.html
Copyright © 2011-2022 走看看