java并发编程实战:第二章----线程安全性
一个对象是否需要是线程安全的取决于它是否被多个线程访问。
当多个线程访问同一个可变状态量时如果没有使用正确的同步规则,就有可能出错。解决办法:
- 不在线程之间共享该变量
- 将状态变量修改为不可变的
- 在访问状态变量时使用同步机制
完全由线程安全类构造的程序也不一定是线程安全的,线程安全类中也可以包含非线程安全的类
一、什么是线程安全性
线程安全是指多个线程在访问一个类时,如果不需要额外的同步,这个类的行为仍然是正确的。(因为线程安全类中封装了必要的同步代码)
一个无状态的类是线程安全的。无状态类是指不包含任何域或也没有引用其它类的域。一次特定计算的瞬间状态,会唯一存在本地变量中。
二、原子性
1、竞争条件:由于不恰当的执行时许而出现了不正确的运行结果,当计算的正确性取决于交叉执行的顺序时
错误原因:基于一个可能失效的观察结果进行下一步操作
例1:读取-修改-写入 操作: 当两个线程交叉执行并同时读取到了相同的值,addOne操作便造成了偏差-1的结果。
1 public class Test {
2 private int x = 0;
3 public void addOne(){
4 x++;
5 }
6 }
例2:先检测后执行 操作:没有进行同步操作的单件模式
2、复合操作
概念:包含一组必须以原子方式执行的操作以保证线程的安全性
原子操作是线程安全的 vs 竞争条件是不安全的
在无状态的类中加入一个确保线程安全的状态可以保证该类仍未线程安全的,但加入多个线程安全状态时没有办法保证。
三、加锁机制
1、内置锁:java提供了强制原子性的内置锁机制:synchronized 块,每个java对象都可作为锁,称为内置锁或监视锁
- synchronized(lock){访问或修改共享变量}
- synchronized方法为保证整个方法体为原子的,lock为this
- 静态synchronized方法以Class对象为锁
最多只有一个对象持有该锁,进入同步代码块获得锁,出代码块释放锁
synchronized特性不能被继承,即覆盖方法需要也写synchronized关键字
2、重入
内置锁是可以重入的,即某个线程可以获得它已经持有的锁。(例同步子类方法调用父类方法super.method()会请求它已经有的锁)
JVM提供锁内线程计数器予以保证正确释放锁
四、用锁来保护对象
锁使受保护的代码以串行形式执行。
对于可能被多个线程访问的状态变量,访问它的时候都要加锁,不只是在写入时加锁。
每一个共享的或可变的状态都应该由一个锁保护
锁机制仅仅阻止了其他线程获得同一个锁,而不能防止访问对象
即使每个方法都使用了同步机制,但由他们呢构成的复合操作不一定保证并发正确。
例
1 public add(E e){
2 if(!vector.contains(e))
3 vector.add(e);
4 }
五、活跃性与性能
如果对整个services方法加锁,方法内有某个计算耗时较长时,那么将严重影响效率

修改代码后将绿色箭头指的大计算量部分重同步代码中取出,可以并发操作,改进性能

java并发编程实战:第二章----线程安全性的更多相关文章
- JAVA并发编程实战---第二章:线程安全性
对象的状态是指存储在状态变量中的数据.对象的状态可能包括其他依赖对象的域.例如HashMap的状态不仅存储在HashMap本身,还存储在许多Map.Entry对象中.对象的状态中包含了任何可能影响其外 ...
- Java并发编程实战4章
第4章主要介绍如何构造线程安全类. 在设计线程安全类的过程中,需要包含以下三个基本要素: 找出构成对象状态的所有变量. 找出约束状态变量的不变性条件. 建立对象状态的并发访问管理策略. 构造线程安全类 ...
- java并发编程实战《七》安全性、活跃性以及性能问题
安全性.活跃性以及性能问题 安全性问题 那什么是线程安全呢?其实本质上就是正确性,而正确性的含义就是程序按照我们期望的执行,不要让我们感到意外. 存在共享数据并且该数据会发生变化,通俗地讲就是有多个线 ...
- Java并发编程实战3章
1.同步包括两方面:原子性和可见性. 2.可见性:因为在多线程程序中,如果没有采用正确的同步,有些线程就会得到失效数据. Java内存模型要求,变量的读取操作和写入操作都必须是原子操作,但对于非vol ...
- 【java并发编程实战】-----线程基本概念
学习Java并发已经有一个多月了,感觉有些东西学习一会儿了就会忘记,做了一些笔记但是不系统,对于Java并发这么大的"系统",需要自己好好总结.整理才能征服它.希望同仁们一起来学习 ...
- Java并发编程实战---第六章:任务执行
废话开篇 今天开始学习Java并发编程实战,很多大牛都推荐,所以为了能在并发编程的道路上留下点书本上的知识,所以也就有了这篇博文.今天主要学习的是任务执行章节,主要讲了任务执行定义.Executor. ...
- 《Java并发编程实战》/童云兰译【PDF】下载
<Java并发编程实战>/童云兰译[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062521 内容简介 本书深入浅出地介绍了Jav ...
- 《java并发编程实战》笔记
<java并发编程实战>这本书配合并发编程网中的并发系列文章一起看,效果会好很多. 并发系列的文章链接为: Java并发性和多线程介绍目录 建议: <java并发编程实战>第 ...
- [书籍翻译] 《JavaScript并发编程》 第二章 JavaScript运行模型
本文是我翻译<JavaScript Concurrency>书籍的第二章 JavaScript运行模型,该书主要以Promises.Generator.Web workers等技术来讲解J ...
- Java并发编程实战 04死锁了怎么办?
Java并发编程文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 前提 在第三篇 ...
随机推荐
- VS2013编译64位OpenSSL(附32位)
安装ActivePerl 这个没什么好说的,直接运行msi即可. 编译OpenSSL 1.使用Visual Studio Tool中的“VS2013 x64 本机工具命令提示”来打开控制台:也可以打开 ...
- 转 shell 命令 http://www.cnblogs.com/me115/p/3427319.html
http://www.cnblogs.com/me115/p/3427319.html 本文将介绍Linux下使用Shell处理文本时最常用的工具:find.grep.xargs.sort.uniq. ...
- C++ 函数特性_参数默认值
函数参数默认值写法 有默认参数值的参数必须在参数表的最右边 ,) // 这是正确的写法 , int k) // 这是错误写法 先声明,后定义 在写函数时要先在代码前面声明,然后再去定义. 函数默认参数 ...
- Hive 查看日志
日志记录了程序运行的过程,是一种查找问题的利器. Hive中的日志分为两种1. 系统日志,记录了hive的运行情况,错误状况.2. Job 日志,记录了Hive 中job的执行的历史过程. 系统日志存 ...
- 八.jQuery源码解析之get()
理论上get是用来返回jQuery对象中部分或全部元素为数组的,但是转换为数组后, 数组中的单个元素又是一个一个dom元素.所以get还有另外一个功效,就是将jQuery对象转换成dom对象. 如果g ...
- WebStorm live edit 浏览器实现同步实现步骤
1.打开WebStore的设置对话框,找到live edit选项,选中Enable live editing. 2.打开Chrome浏览器,进入Chrome网上商店,搜索JetBrains IDE S ...
- mysql修复表
数据库Table xxx is marked as crashed and should be repaired错误的解决方法服务器断电等原因可能导致数据表损坏,导致访问的时候提示:Table xxx ...
- Spring Cloud Eureka的基础架构
基础架构 服务注册中心:Eureka提供的服务端,提供服务注册于发现的功能,也就是在上一节中我们实现的eureka-server 服务提供者:提供服务的应用,可以是springBoot应用,也可以是其 ...
- Best free online svn repositories
Maybe you want to develop in a custom team environment or you usualy work on different machines (tha ...
- NBU 还原windows ORACLE数据库(BW)
将0.92数据库还原到1.92,还原时间7月13日 1.查询所需要的控制日志 bplist -C bw-prd01 -s -- -e -- -k oracle_bw-prd01_0_92_arch - ...