一个对象是否需要是线程安全的取决于它是否被多个线程访问

多个线程访问同一个可变状态量时如果没有使用正确的同步规则,就有可能出错。解决办法:

  • 不在线程之间共享该变量
  • 将状态变量修改为不可变的
  • 在访问状态变量时使用同步机制

完全由线程安全类构造的程序也不一定是线程安全的,线程安全类中也可以包含非线程安全的类

一、什么是线程安全性

线程安全是指多个线程在访问一个类时,如果不需要额外的同步,这个类的行为仍然是正确的。(因为线程安全类中封装了必要的同步代码)

一个无状态的类是线程安全的。无状态类是指不包含任何域或也没有引用其它类的域。一次特定计算的瞬间状态,会唯一存在本地变量中。

二、原子性

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并发编程实战:第二章----线程安全性的更多相关文章

  1. JAVA并发编程实战---第二章:线程安全性

    对象的状态是指存储在状态变量中的数据.对象的状态可能包括其他依赖对象的域.例如HashMap的状态不仅存储在HashMap本身,还存储在许多Map.Entry对象中.对象的状态中包含了任何可能影响其外 ...

  2. Java并发编程实战4章

    第4章主要介绍如何构造线程安全类. 在设计线程安全类的过程中,需要包含以下三个基本要素: 找出构成对象状态的所有变量. 找出约束状态变量的不变性条件. 建立对象状态的并发访问管理策略. 构造线程安全类 ...

  3. java并发编程实战《七》安全性、活跃性以及性能问题

    安全性.活跃性以及性能问题 安全性问题 那什么是线程安全呢?其实本质上就是正确性,而正确性的含义就是程序按照我们期望的执行,不要让我们感到意外. 存在共享数据并且该数据会发生变化,通俗地讲就是有多个线 ...

  4. Java并发编程实战3章

    1.同步包括两方面:原子性和可见性. 2.可见性:因为在多线程程序中,如果没有采用正确的同步,有些线程就会得到失效数据. Java内存模型要求,变量的读取操作和写入操作都必须是原子操作,但对于非vol ...

  5. 【java并发编程实战】-----线程基本概念

    学习Java并发已经有一个多月了,感觉有些东西学习一会儿了就会忘记,做了一些笔记但是不系统,对于Java并发这么大的"系统",需要自己好好总结.整理才能征服它.希望同仁们一起来学习 ...

  6. Java并发编程实战---第六章:任务执行

    废话开篇 今天开始学习Java并发编程实战,很多大牛都推荐,所以为了能在并发编程的道路上留下点书本上的知识,所以也就有了这篇博文.今天主要学习的是任务执行章节,主要讲了任务执行定义.Executor. ...

  7. 《Java并发编程实战》/童云兰译【PDF】下载

    <Java并发编程实战>/童云兰译[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062521 内容简介 本书深入浅出地介绍了Jav ...

  8. 《java并发编程实战》笔记

    <java并发编程实战>这本书配合并发编程网中的并发系列文章一起看,效果会好很多. 并发系列的文章链接为:  Java并发性和多线程介绍目录 建议: <java并发编程实战>第 ...

  9. [书籍翻译] 《JavaScript并发编程》 第二章 JavaScript运行模型

    本文是我翻译<JavaScript Concurrency>书籍的第二章 JavaScript运行模型,该书主要以Promises.Generator.Web workers等技术来讲解J ...

  10. Java并发编程实战 04死锁了怎么办?

    Java并发编程文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 前提 在第三篇 ...

随机推荐

  1. VHF、UHF的频率范围

    1.VHF意思是甚高频,2.UHF意思是超高频,即ultra-high freqency ,电视搜台显示的是当前频率段名,最高不超过470M,因为带增补的高频头标准就是470M3.这是对讲机专业机的工 ...

  2. pgsql的同步须知

    pgsql的同步模式是根据master上的日志来做的同步,有两种同步方式,参考http://www.chinaxing.org/articles/Postgres/2012/12/14/2012-12 ...

  3. iis 更改asp.net 版本设置

    参考来源: https://github.com/neo2018/ZYFC/blob/2e20009097c1e837a6e667a3dffd4224e28f4411/MderFc/Classes/I ...

  4. Windows Server 2012/win8 iis8 上安装 asp.net 4.5 当时用了mvc5 .net framework 4.5 所以得装下

    vs2013+mvc5 +.net framework 4.5  本地 iisexpress 调试一点问题没有,当部署到本机iis时 出现 无法识别 modules错误,具体错误提示是: 锁定是默认设 ...

  5. find 和 find_all 用法

    soup = BeautifulSoup(requests.get(url).text, 'html.parser') soup.find('span', class_='item_hot_topic ...

  6. Lucene根据字段进行自定义搜索扩展

    最近需要对公司的产品搜索功能做一步改动,搜索到的结果首先按照是否有库存进行排序,然后再按照销量.由于库存量也是一个整数,如果直接按照库存量进行倒序排序的话,是不符合要求的,Lucene也没有支持我们这 ...

  7. 史上最全的Angular.js 的学习资源

    Angular.js 的一些学习资源 基础 官方: http://docs.angularjs.org angularjs官方网站已被墙,可看 http://www.ngnice.com/: 官方zi ...

  8. 跟我学算法-tensorflow 实现卷积神经网络

    我们采用的卷积神经网络是两层卷积层,两层池化层和两层全连接层 我们使用的数据是mnist数据,数据训练集的数据是50000*28*28*1 因为是黑白照片,所以通道数是1 第一次卷积采用64个filt ...

  9. 一行代码让App运行时iPhone不会进入锁屏待机状态

    转自:http://www.cocoachina.com/iphonedev/sdk/2010/1028/2260.html 如果你不希望应用运行时 iPhone 进入锁屏待机状态,加入下面这行代码即 ...

  10. UNITY 打APK是如何确定哪些资源有用哪些无用的

    一切从build settings开始,它即是 构建列表,构建运行包当然从它开始. 1,只有在构建列表中的场景和场景引用资源才会被打进包里,其它资源除了2,3位置都不会被打包 2,streamming ...