线程安全

java的线程安全与非线程安全

元气小坏坏 提交于 2019-11-29 06:18:16
线程安全 多线程访问时,对数据进行加锁保护,防止数据出现不一致或者数据污染情况。即:当一个线程要访问某类中的数据时,会对其加锁保护,只有当此线程访问完成后,其它线程才能继续访问 一、线程安全 线程安全指多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。 二、非线程安全 非线程安全值不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。 例如:ArrayList和Vector有什么区别?HashMap和HashTable有什么区别?StringBuilder和StringBuffer有什么区别? 面对这样的问题,回答是:ArrayList是非线程安全的,Vector是线程安全的;HashMap是非线程安全的,HashTable是线程安全的;StringBuilder是非线程安全的,StringBuffer是线程安全的。 总结: 非线程安全是指多线程操作同一个对象可能会出现问题。而线程安全则是多线程操作同一个对象不会有问题。 线程安全必须要使用很多synchronized关键字来同步控制,所以必然会导致性能的降低。 所以在使用的时候,如果是多个线程操作同一个对象,那么使用线程安全的Vector;否则,就使用效率更高的ArrayList。 来源: https

java-同步容器

拈花ヽ惹草 提交于 2019-11-29 05:17:17
为什么会出现同步容器 java集合框架图 在Java的集合容器框架中,主要有四大类别:List、Set、Queue、Map。 List、Set、Queue接口分别继承了Collection接口,Map本身是一个接口。 Collection和Map是一个顶层接口,而List、Set、Queue则继承了Collection接口,分别代表数组、集合和队列这三大类容器。 ArrayList、LinkedList都是实现了List接口,HashSet实现了Set接口,而Deque(双向队列,允许在队首、队尾进行入队和出队操作)继承了Queue接口,PriorityQueue实现了Queue接口。另外LinkedList(实际上是双向链表)实现了了Deque接口和List接口。 像ArrayList、LinkedList、HashMap这些容器都是非线程安全的。如果有多个线程并发地访问这些容器时,就会出现问题。 Java中的同步容器类 java中的同步容器主要分为两大类: Vector、Stack、HashTable Vector实现了List接口,Vector实际上就是一个数组,和ArrayList类似,但是Vector中的方法都是synchronized方法,即进行了同步措施。 Stack也是一个同步容器,它的方法也用synchronized进行了同步,它实际上是继承于Vector类。

Hashmap如何实现线程安全

落爺英雄遲暮 提交于 2019-11-29 04:58:44
方法1:使用hashtable 方法2:使用java.util.concurrent.concurentHashMap 方法3:使用java.util.collections.synchronizedMap()方法包装 HashMap object,得到线程安全的Map,并在此Map上进行操作。 介绍HashTable: hashtable底层是数组+链表的形式,其中的get、put方法等都是用synchronized修饰的,因此,hashtable是线程安全的,但是执行效率比较低,一般不推荐使用。 介绍synchronizedMap synchronizedMap的线程安全和hashtable一样,都是使用sunchronized方法,将方法上锁。 介绍concurrentHashMap 上图为concurrentHahsMap结构图。 从图中可以看出,一个concurrentHashMap包含多个segment,而segment类似与hashTable,是线程安全的,因此concurrentHashMap是一个segment的数组,当有线程操作时,一个线程会操作一个segment,因此是多线程的同时也是安全的,有几个segment就允许几个线程同时操作。一般操作最先都是将key映射到对应的segment上。 不需要锁整个类,分段锁 来源: https://blog.csdn

彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联

邮差的信 提交于 2019-11-29 04:17:17
Java集合类是个非常重要的知识点,HashMap、HashTable、ConcurrentHashMap等算是集合类中的重点,可谓“重中之重”,首先来看个问题,如面试官问你:HashMap和HashTable有什么区别,一个比较简单的回答是: 1、HashMap是非线程安全的,HashTable是线程安全的。 2、HashMap的键和值都允许有null值存在,而HashTable则不行。 3、因为线程安全的问题,HashMap效率比HashTable的要高。 能答出上面的三点,简单的面试,算是过了,但是如果再问:Java中的另一个线程安全的与HashMap极其类似的类是什么?同样是线程安全,它与HashTable在线程同步上有什么不同?能把第二个问题完整的答出来,说明你的基础算是不错的了。带着这个问题,本章开始深入解析HashMap和HashTable类应用而生!总想在文章的开头说点儿什么,但又无从说起。从最近的一些面试说起吧,感受就是:知识是永无止境的,永远不要觉得自己已经掌握了某些东西。如果对哪一块知识感兴趣,那么,请多多的花时间,哪怕最基础的东西也要理解它的原理,尽量往深了研究,在学习的同时,记得多与大家交流沟通,因为也许某些东西,从你自己的角度,是很难发现的,因为你并没有那么多的实验环境去发现他们。只有交流的多了,才能及时找出自己的不足,才能认识到:“哦

线程安全

拜拜、爱过 提交于 2019-11-29 03:36:59
线程安全 可重入/不可重入:针对函数,多个执行流中是否可以同时进入函数运行而不出现问题 概念:指多个线程同时处理操作临界资源而不会出现数据二义性,则称是线程安全的 二义性:在线程中是否对临界资源进行了非原子操作 如何实现线程安全: 同步(保证合理):临界资源的合理访问(时序可控) 互斥(保证安全):临界资源同一时间唯一访问 如何实现互斥:(首先自身是安全的) 互斥锁:(黄牛抢票程序) 使用一个0/1的原子操作的计数器(图片): 1 -> 表示可以加锁,加锁就是计数-1 . 操作完毕后要解锁,解锁就是计数+1 0 -> 表示不可以加锁,不能加锁则等待 操作步骤: 1.定义互斥锁变量 pthread_mutex_t mutex; 2.初始化互斥锁变量 int pthread_mutex_init() 3.加锁/解锁--->要在临界资源访问之前进行 阻塞加锁,加不上锁就阻塞: int pthread_mutex_lock() 非阻塞加锁,加不上则直接报错返回: int pthread_mutex_trylock() 限时阻塞加锁: int pthread_mutex_timedlock() *加锁之后要在线程任意有可能退出的地方解锁 解锁: int pthread_mutex_unlock() 4.销毁互斥锁 int pthread_mutex_destroy() 死锁:

Java数据结构之LinkedList、ArrayList的效率分析

不想你离开。 提交于 2019-11-29 03:27:37
Java数据结构之LinkedList、ArrayList的效率分析 前言: 在我们平常开发中难免会用到List集合来存储数据,一般都会选择ArrayList和LinkedList,以前只是大致知道ArrayList查询效率高LinkedList插入删除效率高,今天来实测一下。 先了解一下List List列表类,顺序存储任何对象(顺序不变),可重复。 List是继承于Collection的接口,不能实例化。实例化可以用: ArrayList(实现动态数组),查询快(随意访问或顺序访问),增删慢。整体清空快,线程不同步(非线程安全)。数组长度是可变的百分之五十延长 LinkedList(实现链表),查询慢,增删快。 Vector(实现动态数组),都慢,被ArrayList替代。长度任意延长。线程安全(同步的类,函数都是synchronized) Stack(实现堆栈)继承于Vector,先进后出。 L ist基本操作 插入:add() 查找:get() 删除:remove(int index) 修改:set() 清空表:clear() 遍历:用Iterator迭代器遍历每个元素 ArrayList、LinkedList性能对比 为了很好的对比效率,直接写个测试程序看下运行结果 模拟5w条数据指定插入第一位,然后查询全部,循环删除第一位,下面是测试ArrayList函数

HashMap与ConcurrentHashMap原理剖析

扶醉桌前 提交于 2019-11-29 01:17:07
HashMap与ConcurrentHashMap原理剖析 HashMap是基于 哈希表 的Map接口的实现。此实现提供所有可选的映射操作,并允许使用 null值 和null键。(除了不同步和允许使用null之外,HashMap类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。另外,HashMap是非 线程安全 的,也就是说在 多线程 的环境下,可能会存在问题,不像Hashtable是线程安全的。 ConcurrentHashMap结构与HashMap大致相同,为了实现线程安全,其比起HashMap的实现显得更加庞大。ConcurrentHashMap的数据结构和同步机制给自身提供了良好的多线程安全以及惊人的异步读取能力。 相信有经验的开发者都会注意到,在项目中总是会把两者混合使用;那么到底什么是线程安全呢?这可能是很多初学者带有的疑问,难道ConcurrentHashMap能保证多个线程的更新都保留吗?所谓的线程安全并不是那么厉害的东西,其实就是利用同步机制(锁)来保证其不会有多个Put操作同时作用。其实在这一点上Hashtable已经做到了,而ConcurrentHashMap可以比Hashtable限制更少从而更加高效。接下来从他们各自的原理来剖析。 HashMap原理 HashMap顾名思义,是由hash值来做映射的映射表<Key

Java入门系列之StringBuilder、StringBuffer(三)

♀尐吖头ヾ 提交于 2019-11-29 00:52:13
前言 上一节我们讲解了字符串的特性,除了字符串类外,还有两个我们也会经常用到的类,那就是StringBuffer和StringBuilder。因为字符串不可变,所以我们每次对字符串的修改比如通过连接concat、trim等都会创建一个新的字符串对象,那么我们如何在不创建字符串垃圾(大量临时的字符串)的 情况下操作字符串呢?答案则是使用StringBuffer和StringBuilder,StringBuffer是旧类,但是在Java 5中新增了StringBuilder,并且在Enum,Generics等和Java中的Autoboxing方面进行了重大改进。 StringBuffer VS StringBuilder String和StringBuffer之间的主要区别是String是不可变的,而StringBuffer、StringBuilder可变,这也就意味着我们可以在创建StringBuffer对象时修改它而不创建任何新对象,这个可变属性使StringBuffer成为处理Java中的字符串的理想选择,同时,这种可变性更加节省时间并且资源消耗更少。当然我们可以通过toString将StringBuffer转换为String。这两个类几乎相同,它们使用具有相同名称的方法返回相同的结果

JAVA 并发编程- Spring 并发访问的线程安全性问题

那年仲夏 提交于 2019-11-29 00:45:19
首先对于Spring的IOC来说,对象是由Spring来帮我们管理,也就是在Spring启动的时候,在Spring容器中,由Spring给我们创建的,Spring会帮我们维护,一般都是单例的,也就是一个对象。 spring生成对象默认是单例的。通过scope属性可以更改为多例。 第一部分:验证Spring生成对象默认是单例的。 下面我们来一个网上的例子验证一下: <bean id="singleton" class="java.util.Date" scope="singleton"></bean> <bean id="prototype" class="java.util.Date" scope="prototype"></bean> package test; import java.util.Date; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.opensymphony.xwork2.ActionContext; public class TestScope { public static void main(String[] args)

ArrayList 和 Vector 的区别

微笑、不失礼 提交于 2019-11-29 00:09:33
这两个类都实现了 List 接口(List 接口继承了 Collection 接口),他们都是有序集合, 即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以 按位置索引号取出某个元素,并且其中的数据是允许重复的。 接着说 ArrayList 与 Vector 的区别,这主要包括两个方面: 1、同步性: Vector 是线程安全的,也就是说是它的方法之间是线程同步的,而 ArrayList 是线程 序不安全的,它的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好是使 用 ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最 好是使用 Vector,因为不需要我们自己再去考虑和编写线程安全的代码。 备注:对于 Vector&ArrayList、Hashtable&HashMap,要记住线程安全的问题,记住 Vector 与 Hashtable 是旧的,是 java 一诞生就提供了的,它们是线程安全的,ArrayList 与 HashMap 是 java2 时才提供的,它们是线程不安全的。 2、数据增长: ArrayList 与 Vector 都有一个初始的容量大小,当存储进它们里面的元素的个数超过 了容量时,就需要增加 ArrayList 与 Vector 的存储空间,每次要增加存储空间时,不是只