线程并发线程安全介绍及java.util.concurrent包下类介绍
线程Thread,在Java开发中多线程是必不可少的,但是真正能用好的并不多!
首先开启一个线程三种方式
①new Thread(Runnable).start()
②thread.start(); //thread类必须继承Thread
③Executor pool = Executors.newFixedThreadPool(7);pool.execute(new Runnable() ); //利用线程池
转载:http://blog.csdn.net/king866/article/details/53945400
在多线程并发则一定会带来线程安全的问题,如何解决线程安全
线程的安全控制有三个级别
•
JVM 级别。大多数现代处理器对并发对 某一硬件级别提供支持,通常以 compare-and-swap (CAS)指令形式。CAS
是一种低级别的、细粒度的技术,它允许多个线程更新一个内存位置,同时能够检测其他线程的冲突并进行恢复。它是许多高性能并发算法的基础。在 JDK
5.0 之前,Java 语言中用于协调线程之间的访问的惟一原语是同步,同步是更重量级和粗粒度的。公开
CAS 可以开发高度可伸缩的并发 Java 类。
• 低级实用程序类 -- 锁定和原子类。使用 CAS 作为并发原语,ReentrantLock 类提供与 synchronized
原语相同的锁定和内存语义,然而这样可以更好地控制锁定(如计时的锁定等待、锁定轮询和可中断的锁定等待)和提供更好的可伸缩性(竞争时的高性能)。大多数开发人员将不再直接使用
ReentrantLock 类,而是使用在 ReentrantLock 类上构建的高级类。
• 高级实用程序类。这些类实现并发构建块,每个计算机科学课本中都会讲述这些类 --
信号、互斥、闩锁、屏障、交换程序、线程池和线程安全集合类等。大部分开发人员都可以在应用程序中用这些类,来替换许多同步、 wait() 和
notify() 的使用,从而提高性能、可读性和正确性。
常见的线程安全操作
①加锁同步 synchronized Lock等
②wait() notify()线程调度 已实现执行的同步
③ThreadLocal局部变量 每一个线程都有一份数据
④Semaphore 信号量
⑤volatile 保证一个变量的线程安全
等 等
接下来讨论集合的多线程安全
原始集合框架包含三个接口:List、Map 和 Set。这三种集合是我们平常使用最多的集合,当集合遇到多线程时,我们必须要考虑多线程的问题,
比如说一个线程1不断读取集合线程2不断往集合放入数据,这时就会出现问题
我们都知道vector,hashtable是在Java1.0就引入的集合,两个都是线程安全的,但是现在已很少使用,原因就是内部实现的线程安全太消耗资源
java.util.concurrent 是什么?
java.util.concurrent
包含许多线程安全、测试良好、高性能的并发构建块。创建 java.util.concurrent 的目的就是要实现 Collection
框架对数据结构所执行的并发操作。通过提供一组可靠的、高性能并发构建块,开发人员可以提高并发类的线程安全、可伸缩性、性能、可读性和可靠性,
java.util.concurrent 中有很多线程安全集合、线程池、信号和同步工具
要成为线程安全的类,在从多个线程访问时,它必须继续正确运行,而不管运行时环境执行那些线程的调度和交叉,且无需对部分调用代码执行任何其他同步。结果是对线程安全对象的操作将用于按固定的整体一致顺序出现所有线程。
JDK 1.2 中引入的 Collection
框架是一种表示对象集合的高度灵活的框架,它使用基本接口 List、Set 和 Map。通过 JDK
提供每个集合的多次实现(HashMap、Hashtable、TreeMap、WeakHashMap、HashSet、TreeSet、
Vector、ArrayList、LinkedList 等等)。
java.util.concurrent 包添加了多个新的线程安全集合类(ConcurrentHashMap、CopyOnWriteArrayList 和CopyOnWriteArraySet)这些类的目的是提供高性能、高度可伸缩性、线程安全的基本集合类型版本
通过同步的封装工厂(Collections.synchronizedMap()、synchronizedList() 和 synchronizedSet()),非线程安全集合均可表现为线程安全的
java.util 中的线程集合仍有一些缺点。例如,在迭代锁定时,通常需要将该锁定保留在集合中,否则,会有抛出 ConcurrentModificationException
的危险。此外,如果从多个线程频繁地访问集合,则常常不能很好地执行这些类。
JDK 5.0 还提供了两个新集合接口 -- Queue 和 BlockingQueue。Queue 接口与 List 类似,但它只允许从后面插入,从前面删除。通过消除 List 的随机
访问要求,可以创建比现有 ArrayList 和 LinkedList 实现性能更好的 Queue 实现。因为 List 的许多应用程序实际上不需要随机访问,所以Queue 通常
可以替代 List,来获得更好的性能。
ConcurrentModificationException这个问题我也遇到过,即便加上同步操作依然不能安全的并发操作,问题的根源还是在于Iterator迭代一致性的
原因
弱一致的迭代器
java.util 包中的集合类都返回 fail-fast 迭代器,这意味着它们假设线程在集合内容中进行迭代时,集合不会更改它的内容。如果 fail-fast 迭代器检测到
在迭代过程中进行了更改操作,那么它会抛出 ConcurrentModificationException,这是不可控异常。在迭代过程中不更改集合的要求通常会对许多并发
应用程序造成不便。相反,比较好的是它允许并发修改并确保迭代器只要进行合理操作,就可以提供集合的一致视图,如 java.util.concurrent 集合类中
的迭代器所做的那样。java.util.concurrent 集合返回的迭代器称为弱一致的(weakly consistent)迭代器。对于这些类,如果元素自从迭代开始已经删
除且尚未由 next() 方法返回,那么它将不返回到调用者。如果元素自迭代开始已经添加,那么它可能返回调用者,也可能不返回。在一次迭代中,无论
如何更改底层集合,元素不会被 返回两次
可以用两种方法创建线程安全支持数据的 List -- Vector 或封装 ArrayList 和 Collections.synchronizedList()。
但是java.util.concurrent 包添加了名称繁琐的 CopyOnWriteArrayList。
为什么我们想要新的线程安全的List类?为什么会出现CopyOnWriteArrayList?
简单的答案是与迭代和并发修改之间的交互有关。使用 Vector 或使用同步的 List 封装器,返回的迭代器是 fail-fast 的,
这意味着如果在迭代过程中任何其他线程修改 List,迭代可能失败。Vector 的非常普遍的应用程序是存储通过组件注册的监听器的列表。当发生适合的事件时,该组件将在监听器的列表中迭代,调用每个监听器。
为了防止 ConcurrentModificationException,迭代线程必须复制列表或锁定列表,以便进行整体迭代,而这两种情况都需要大量的性能成本。CopyOnWriteArrayList 类通过每次添加或删除元素时创建支持数组的新副本,避免了这个问题,但是进行中的迭代保持对创建迭代器时的当前副本进行操作。虽然复制也会有一些成本,但
是在许多情况下,迭代要比修改多得多,
在这些情况下,写入时复制要比其他备用方法具有更好的性能和并发性。
除了CopyOnWriteArrayList,还有CopyOnWriteArraySet、ConcurrentHashMap
ConcurrentLinkedQueue 快速、线程安全的、无阻塞 FIFO 队列
java.util.concurrent除了这些线程安全的集合还有线程相关的类还有:
①Executor 框架 是java.util.concurrent 包中包含灵活的线程池实现,但是更重要的是,它包含用于管理实现 Runnable
的任务的执行的整个框架
②Future 接口允许表示已经完成的任务、正在执行过程中的任务或者尚未开始执行的任务。通过 Future 接口,可以尝试取消尚未完成的任务,
查询任务已经完成还是取消了,以及提取(或等待)任务的结果值。
③Semaphore、CyclicBarrier、CountdownLatch 和 Exchanger 类都是同步工具的例子。每个类都有线程可以调用的方法,
方法是否被阻塞取决于正在使用的特定同步工具的状态和规则。
Executor 线程池的几种模型
1、newFixedThreadPool创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数
则将提交的任务存入到池队列中。
2、newCachedThreadPool创建一个可缓存的线程池。这种类型的线程池特点是:
3、newSingleThreadExecutor创建一个单线程化的Executor,即只创建唯一的工作者线程来执行任务,如果这个线程异常结束,会有另一个取代它
保证顺序执行(我觉得这点是它的特色)。单工作线程最大的特点是可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的 。
4、newScheduleThreadPool创建一个定长的线程池,而且支持定时的以及周期性的任务执行,类似于Timer。
线程并发线程安全介绍及java.util.concurrent包下类介绍的更多相关文章
- 高并发编程基础(java.util.concurrent包常见类基础)
JDK5中添加了新的java.util.concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的访问都串行化了,这样保证了线程的安全性,所以这种方法 ...
- 《java.util.concurrent 包源码阅读》 结束语
<java.util.concurrent 包源码阅读>系列文章已经全部写完了.开始的几篇文章是根据自己的读书笔记整理出来的(当时只阅读了部分的源代码),后面的大部分都是一边读源代码,一边 ...
- 《java.util.concurrent 包源码阅读》13 线程池系列之ThreadPoolExecutor 第三部分
这一部分来说说线程池如何进行状态控制,即线程池的开启和关闭. 先来说说线程池的开启,这部分来看ThreadPoolExecutor构造方法: public ThreadPoolExecutor(int ...
- 【并发编程】【JDK源码】JDK的(J.U.C)java.util.concurrent包结构
本文从JDK源码包中截取出concurrent包的所有类,对该包整体结构进行一个概述. 在JDK1.5之前,Java中要进行并发编程时,通常需要由程序员独立完成代码实现.当然也有一些开源的框架提供了这 ...
- 深入理解java:2.3. 并发编程 java.util.concurrent包
JUC java.util.concurrent包, 这个包是从JDK1.5开始引入的,在此之前,这个包独立存在着,它是由Doug Lea开发的,名字叫backport-util-concurrent ...
- java.util.concurrent包详细分析--转
原文地址:http://blog.csdn.net/windsunmoon/article/details/36903901 概述 Java.util.concurrent 包含许多线程安全.测试良好 ...
- java.util.concurrent包
在JavaSE5中,JUC(java.util.concurrent)包出现了 在java.util.concurrent包及其子包中,有了很多好玩的新东西: 1.执行器的概念和线程池的实现.Exec ...
- java.util.concurrent包API学习笔记
newFixedThreadPool 创建一个固定大小的线程池. shutdown():用于关闭启动线程,如果不调用该语句,jvm不会关闭. awaitTermination():用于等待子线程结束, ...
- 《java.util.concurrent 包源码阅读》02 关于java.util.concurrent.atomic包
Aomic数据类型有四种类型:AomicBoolean, AomicInteger, AomicLong, 和AomicReferrence(针对Object的)以及它们的数组类型, 还有一个特殊的A ...
随机推荐
- 解决Eclipse中新创建的Maven项目不自动创建web.xml文件
1. 通过J2EE tools 2.项目右键-properties-project facets-勾选dynamic web moudle
- 在服务器上运行db:seed数据填充时,出错的问题解决
在服务器上运行db:seed数据填充时,出错的问题解决 运行composer dump-autoload
- jdk版本对应数字
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springfr ...
- ffmpeg采集帧出错不退出的补丁
在ffmpeg2.81.11和ffmpeg3.0.7上试验.ffmpeg没有FFERROR_REDO常量定义,但ffmpeg3.0.7上有. diff --git a/libavdevice/v4l2 ...
- Jqmobile Secha Ionic比较
1. Jqmobile 轻量级框架,它的语言基于 jquery 语言容易上手,运行速度快,但是没有 MVC 多人协作 开发的概念,项目比较大后 代码不易维护 (中小项目 1-2 个人开发很适 ...
- HR-人力资源管理系统(Human Resources Management System,HRMS)
人力资源管理系统(Human Resources Management System,HRMS),是指组织或社会团体运用系统学理论方法,对企业的人力资源管理方方面面进行分析.规划.实施.调整,提高企业 ...
- app添加引导页
1.设置guide.html 2.登陆或者主页面引用guide.html mui.plusReady(function() { //读取本地存储,检查是否为首次启动 决定是否显示引导页 var sho ...
- [转]Jsp 与 JavaBean
JavaBean 是一个遵循特定写法的 Java 类,它有以下特点: 1. Java 类具有一个无参的构造函数 2. 属性必须私有化. 3. 私有化的属性通过 public 类型的方法暴露给其它程序, ...
- json中key大小写转换
最近工作中遇到json格式的字符串中的key为大写的,需要转换成小写的来解析,开始想使用正则来替换,结果不是很方便,后来考虑把JSONObject重新来封装. 如下json格式:{PWACHECKIN ...
- Golang后台开发初体验
转自:http://blog.csdn.net/cszhouwei/article/details/37740277 补充反馈 slice 既然聊到slice,就不得不提它的近亲array,这里不太想 ...