并发编程之synchronized(二)------jvm对synchronized的优化
一、锁的粗化
看如下代码
public class Test {
StringBuffer stb = new StringBuffer(); public void test1(){
//jvm的优化,锁的粗化
stb.append("1"); stb.append("2"); stb.append("3"); stb.append("4");
}
首先我们要清除StringBuffer是线程安全的,因为它在每一个方法上都加了synchronized锁,下图是StringBuffer的源码
按照正常的理解synchronized是对当前对象加锁,那么我们调用了四次append方法,那么jvm是将这把对象锁加了四次吗?如下图:
那这样的化,jvm就需要加四次锁,当然也要释放四次锁,频繁加解锁引起线程上下文的切换,非常消耗性能,所以jvm做了优化,只加一次锁,叫做锁的粗化,可以理解为将锁的颗粒度放大
二、锁的消除
如图看下面代码
public void test2(){
//jvm的优化,JVM不会对同步块进行加锁
synchronized (new Object()) {
//伪代码:很多逻辑
//jvm是否会加锁?
//jvm会进行逃逸分析
}
}
这个地方加锁等于没有加锁,因为每个线程都会new object,大家都不会用同一把锁,jvm分析优化后不会对这种代码加锁(逃逸分析),所以,我们平时加锁一定要注意,加锁要加同一把锁。
三、锁的膨胀升级
1、锁的升级
synchronized的锁的状态总共有四种,无锁状态、偏向锁、轻量级锁和重量级锁。随着锁的竞争,锁可以从偏向锁升级到轻量级锁,再升级的重量级锁,但是锁的升级是单向的,也就是说只能从低到高升级,锁状态的升级不可逆。
JDK1.6版本之后对synchronized的实现进行了各种优化,如自旋锁、偏向锁和轻量级锁 并默认开启偏向锁 开启偏向锁:-XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0 关闭偏向锁:-XX:-UseBiasedLocking。如果直接上来就是重量级锁,那么实在是太消耗资源了。
2、锁的状态记录在哪里
3、对锁的理解:
4、锁的膨胀升级过程
注意一下几点:
线程1获取轻量级锁后会将Object Mark Word 复制自己的一份到自己的栈空间,然后在自己的栈空间开辟一个指针lockerecord 指向Object Mark Word,同时Object Mark Word也会指向lockerecord,当线程1执行完代码块释放轻量级锁之后,发现Object Mark Word不在指向自己,说明当前锁已经改为重量级锁,那么它会唤醒阻塞队列中所有线程重新竞争锁。
总结:偏向锁,轻量级锁都是基于Object Mark Word的标记实现,java尽可能避免使用重量级锁。
并发编程之synchronized(二)------jvm对synchronized的优化的更多相关文章
- Java并发编程之CAS二源码追根溯源
Java并发编程之CAS二源码追根溯源 在上一篇文章中,我们知道了什么是CAS以及CAS的执行流程,在本篇文章中,我们将跟着源码一步一步的查看CAS最底层实现原理. 本篇是<凯哥(凯哥Java: ...
- 并发编程之ThreadLocal、Volatile、synchronized、Atomic关键字扫盲
前言 对于ThreadLocal.Volatile.synchronized.Atomic这四个关键字,我想一提及到大家肯定都想到的是解决在多线程并发环境下资源的共享问题,但是要细说每一个的特点.区别 ...
- Java并发编程之CAS第三篇-CAS的缺点及解决办法
Java并发编程之CAS第三篇-CAS的缺点 通过前两篇的文章介绍,我们知道了CAS是什么以及查看源码了解CAS原理.那么在多线程并发环境中,的缺点是什么呢?这篇文章我们就来讨论讨论 本篇是<凯 ...
- python并发编程之multiprocessing进程(二)
python的multiprocessing模块是用来创建多进程的,下面对multiprocessing总结一下使用记录. 系列文章 python并发编程之threading线程(一) python并 ...
- 并发编程之J.U.C的第二篇
并发编程之J.U.C的第二篇 3.2 StampedLock 4. Semaphore Semaphore原理 5. CountdownLatch 6. CyclicBarrier 7.线程安全集合类 ...
- 并发编程之:CountDownLatch
大家好,我是小黑,一个在互联网苟且偷生的农民工. 先问大家一个问题,在主线程中创建多个线程,在这多个线程被启动之后,主线程需要等子线程执行完之后才能接着执行自己的代码,应该怎么实现呢? Thread. ...
- Java并发编程之CAS
CAS(Compare and swap)比较和替换是设计并发算法时用到的一种技术.简单来说,比较和替换是使用一个期望值和一个变量的当前值进行比较,如果当前变量的值与我们期望的值相等,就使用一个新值替 ...
- 并发编程之wait()、notify()
前面的并发编程之volatile中我们用程序模拟了一个场景:在main方法中开启两个线程,其中一个线程t1往list里循环添加元素,另一个线程t2监听list中的size,当size等于5时,t2线程 ...
- 并发编程之:JMM
并发编程之:JMM 大家好,我是小黑,一个在互联网苟且偷生的农民工. 上一期给大家分享了关于Java中线程相关的一些基础知识.在关于线程终止的例子中,第一个方法讲到要想终止一个线程,可以使用标志位的方 ...
- 并发编程之:ThreadLocal
大家好,我是小黑,一个在互联网苟且偷生的农民工. 从前上一期[并发编程之:synchronized] 我们学到要保证在并发情况下对于共享资源的安全访问,就需要用到锁. 但是,加锁通常情况下会让运行效率 ...
随机推荐
- python生成批量格式化字符串
在学习tensorflow管道化有关操作时,有一个操作是先生成一个文件名队列.在书上使用了这样的代码: filenames = ['test%d.txt'%i for in in range(1,4) ...
- python中那些鲜为人知的功能特性
经常逛GitHub的可能关注一个牛叉的项目,叫 What the f*ck Python! 这个项目列出了几乎所有python中那些鲜为人知的功能特性,有些功能第一次遇见时,你会冒出 what the ...
- Jmeter之仿真高并发测试-集合点
场景: 大家在使用Jmeter测试的时候应该发现了, (1)线程启动了就会直接发送测试请求:--如果要模拟在一瞬间高并发量测试的时候,需要调高线程数量,这很耗测试机器的性能,往往无法支持较大的并发数, ...
- es性能调优---写优化操作
ES 的默认配置,是综合了数据可靠性.写入速度.搜索实时性等因素.实际使用时,我们需要根据公司要求,进行偏向性的优化. 写优化 假设我们的应用场景要求是,每秒 300 万的写入速度,每条 500 字节 ...
- SpringMVC中Map、Model、ModelMap、ModelAndView之间的关系及区别
首先,在了解这三者之前,需要知道一点:SpringMVC在调用方法前会创建一个隐含的数据模型(Model),作为模型数据的存储容器, 成为”隐含模型”. 如果controller方法的参数为Moedl ...
- keras训练函数fit和fit_generator对比,图像生成器ImageDataGenerator数据增强
1. [深度学习] Keras 如何使用fit和fit_generator https://blog.csdn.net/zwqjoy/article/details/88356094 ps:解决样本数 ...
- 二.1.vue-开发环境搭建
一vue开发环境搭建 1.下载二进制包 https://nodejs.org/zh-cn/ 直接下一步下一步即可,然后dmd中如下显示说明成功: C:\Program Files\nodejs> ...
- Oracle Solaris 11.4安装桌面/gdb
文章目录 1. 说明 2. 挂载镜像 3. 安装桌面 4. 安装gdb 5. 重启OS 1. 说明 该文承接上文Solaris 11.4安装,映像包管理系统(IPS)搭建. Solaris 11.4的 ...
- Java编程资料
Java相关免费编程书籍推荐(都是PDF版) 编程进阶 2017年9月11日 IDE IntelliJ IDEA 简体中文专题教程 https://github.com/judasn/IntelliJ ...
- css引入的方式有哪些_四种css的引入方式与特点
在网页中css主要负责html文档的样式显示,目前css主要有4种引入方式:行内式.内嵌式.导入式.链接式. 1.行内式 行内式也叫内联样式,是指标记的style属性中设定CSS样式,这种方式没有体现 ...