深入理解Java虚拟机(第三版)-14. 线程安全与锁优化
14. 线程安全与锁优化
1. 什么是线程安全?
当多个线程同时访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替进行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那就称这个对象是线程安全的
2. Java语言中的线程安全
我们将Java语言下的线程安全分为以下五类:不可变、绝对线程安全、相对线程安全、线程兼容和线程对立。
1.不可变:不可变一定是线程安全的,无论是对象的方法实现还是方法的调用者,都不需要进行任何线程安全保障措施。
例如:final修饰的基本类型变量不可变;类不可变,可以通过将类中的字段全部声明为final,比如Integer
实例:String,枚举类型,java.lang.Number的部分子类,如Long和Double等数值包装类、BigInteger和BigDecimal等大数据类型。但Number下的原子类AtomicInteger等是可变的
2.绝对线程安全:需要达到1中的条件,一个类要达到”不管运行时环境如何,调用者都不需要进行额外的同步措施“的条件,需要付出高昂甚至不切实际的代价。
Java API中标注线程安全的类,都不是绝对的线程安全。例如Vector,如果要做到绝对安全,需要在内部维护一组一致性的快照访问才行,每次针对其中元素进行改动时,都要产生新的快照,这样代价很大。
3.相对线程安全:即通常意义上的线程安全,保证对这个对象的单次操作是安全的,调用时不需要额外的保障措施;但是连续的调用操作,需要调用端使用额外的同步手段。
4.线程兼容:对象本身不安全,但是通过调用端正确使用同步手段来保证对象在并发环境下的安全使用。
Java中大多数类是线程兼容的,比如HashMap、ArrayList
5.线程对立:不管调用方是否采取了同步措施,都无法在多线程环境下保证线程安全。
Thread的suspend()和resume();System.setIn()和 setOut()
3.线程安全的实现方法(倾向于虚拟机如何实现同步与锁)
1.互斥同步
互斥的实现方式:临界区(Critical Section)、互斥量(Mutex)和信号量(Semaphore)。
Java中,最基本的互斥手段是Synchronized,synchronized关键字在经过javac编译之后,会在同步块前后行程moniterenter和moniterexit两个字节码指令。这两个字节码指令都需要一个reference类型的参数来指明要锁定和解锁的对象。如果没有指定,将根据synchronized修饰的方法类型(如实例方法或类方法)来决定线程持有的锁是代码所在的对象实例还是类型对应的Class对象。
Java虚拟机规范要求,在执行moniterenter时,首先去获取对象的
深入理解Java虚拟机(第三版)-14. 线程安全与锁优化的更多相关文章
- 《深入理解Java虚拟机》-----第13章 线程安全与锁优化
概述 在软件业发展的初期,程序编写都是以算法为核心的,程序员会把数据和过程分别作为独立的部分来考虑,数据代表问题空间中的客体,程序代码则用于处理这些数据,这种思维方式直接站在计算机的角度去抽象问题和解 ...
- 《深入理解 Java 虚拟机》读书笔记:线程安全与锁优化
正文 一.线程安全 当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那 ...
- 深入理解Java虚拟机第三版,总结笔记【随时更新】
最近一直在看<深入理解Java虚拟机>第三版,无意中发现了第三版是最近才发行的,听说讲解的JDK版本升级,新增了近50%的内容. 这种神书,看懂了,看进去了,真的看的很快,并没有想象中的晦 ...
- 深入理解java虚拟机(三)对象回收判断算法以及死亡过程
在堆里面存放着Java几乎所有的对象实例,垃圾收集器要进行垃圾回收,要做的第一步便是找出那些对象是需要回收的. 怎么判断对象是否需要回收? 常用的方法有两种. 1.引用计数算法.为每一个对象添加一个引 ...
- 深入理解Java虚拟机读书笔记7----晚期(运行期)优化
七 晚期(运行期)优化 1 即时编译器(JIT编译器) ---当虚拟机发现某个方法或代码块的运行特别频繁时,就会把这些代码认定为“热点代码”,包括被多次调用的方法和被多次执行的循环体. ...
- 深入理解Java虚拟机 第三章 垃圾收集器 笔记
1.1 垃圾收集器 垃圾收集器是内存回收的具体实现.以下讨论的收集器是基于JDK1.7Update14之后的HotSpot虚拟机.这个虚拟机包含的所有收集器有: 上图展示了7种作用于不同分代的收集 ...
- 类文件结构——深入理解Java虚拟机 笔记三
在之前的笔记中记录过,Java程序变成可执行文件的步骤是:源代码-->经过编译变成class文件-->经过JVM虚拟机变成可执行的二进制文件.因此,为了对JVM执行程序的过程有一个好的了解 ...
- 重读《深入理解Java虚拟机》三、Java虚拟机执行的数据入口(类文件结构)
1.Java如何实现平台无关系 Java要实现平台无关系就需要在Java代码和本地机器之间引入一个中间层,实现Java代码和本地机器的解耦,而这个中间层就是字节码.字节码独立于本地机器,以实现代码的可 ...
- 深入理解java虚拟机-第三章
1.概述 2.对象已死吗? 引用计数器 给对象添加一个引用计数器,每当有引用时,计数器加1,引用失效时,计数器减1:任何时刻计数器为0的对象就是不可能再被使用的. 若对象是循环引用,则无法处理.JVM ...
随机推荐
- vue中如何缓存一些页面
在vue中,有时候我们只想缓存页面中的一些组件或页面,这个时候怎么办呢,我们就需要用判断来加载keep-alive. 例如: // router.js { path: "/driving_l ...
- d3.js ---画坐标轴
画坐标轴 //使用d3的svg的axis()方法生成坐标轴 var x_axis = d3.svg.axis().scale(scale_x), y_axis = d3.svg.axis().scal ...
- AspNetCore源码解析_1_CORS中间件
概述 什么是跨域 在前后端分离开发方式中,跨域是我们经常会遇到的问题.所谓的跨域,就是处于安全考虑,A域名向B域名发出Ajax请求,浏览器会拒绝,抛出类似下图的错误. JSONP JSONP不是标准跨 ...
- 自动控制理论的MATLAB仿真实例(二)
%求方程的解 x=sym('x'); fx=(3*x*x+2*x)*(x*x+2.32*x+4)-(2*x+2.32)*(x*x*x+x*x) fx =
- HTTP请求中Get和Post请求的区别?
分类 Get的请求方式 1.直接在浏览器地址栏输入某个地址. 2.点击链接地址. 3.表单的默认提交方式或者设置为method="get". Post的请求方式 1.设置表单的me ...
- Fink SQL 实践之OVER窗口
问题场景 Flink SQL 是一种使用 SQL 语义设计的开发语言,用它解决具体业务需求是一种全新体验,类似于从过程式编程到函数式编程的转变一样,需要一个不断学习和实践的过程.在看完了 Flink ...
- JavaScript数组排序(冒泡排序、选择排序、桶排序、快速排序)
* 以下均是以实现数组的从小到大排序为例 1.冒泡排序 先遍历数组,让相邻的两个元素进行两两比较 .如果要求小到大排:最大的应该在最后面,如果前面的比后面的大,就要换位置: 数组遍历一遍以后,也就是第 ...
- 广告行业中那些趣事系列7:实战腾讯开源的文本分类项目NeuralClassifier
摘要:本篇主要分享腾讯开源的文本分类项目NeuralClassifier.虽然实际项目中使用BERT进行文本分类,但是在不同的场景下我们可能还需要使用其他的文本分类算法,比如TextCNN.RCNN等 ...
- java-FileUtils(复制文件夹、复制文件、字符串直接写入文件中)(新手)
实例: lx1: import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; pu ...
- redis 持久化RDB、AOF
1.redis持久化简介 Redis是一种高级key-value数据库.它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富.有字符串,链表,集合和有序集合.支持在服务器端计算集合 ...