同步机制之一--Synchronized,以及此机制下的锁的本质和种类
Java中,为了实现同步的操作临界区,线程在执行临界区的代码时,需要获得某个对象的锁。本文介绍获得对象的锁的方法之一----Synchronized关键字。
Synchronized关键字的用法
Class Test {
....
Object o = new Object();
public synchronized test() { //第一种用法
....
}
public test_1 () {
synchronized (o) { //第二种用法
....
}
}
}
Synchronized关键字有两种用法,一种修饰方法,作用在调用此方法的对象;一种修饰代码块,在括号中指定作用的对象。在上面的例子中,在某个线程中创建Test对象 t ,在线程1调用 t.test() 则线程需要获取 t 的锁;调用 t.test_1() 线程则需要 t 持有的对象 o 的锁。
Synchronized机制下锁的本质
锁的本质实际上就是对象的头部几个bit的标志而已,根据这些标志不同,对象又分出了无锁(01),偏向锁(01),轻量级锁(00),重量级锁(10),锁可以从左至右逐渐升级,却不能降级。具体如下表格

由于 01 状态可以表示两种锁,因此 锁标志为01时,还要检查偏向锁标志,为1表示偏向锁,为0表示无锁。
为什么需要这么多种类的锁呢?JDK1.6(应该是)为了解决线程用Synchronized获取锁失败后必须阻塞等待的情况,因为这样效率太低了。下面介绍几种锁的机制。
偏向锁
对象初始的锁默认是偏向锁,可以通过XX: -UseBiasedLocing = false 放弃使用偏向锁,那么所有对象的默认锁就是轻量级锁。当一个对象是偏向锁时,对象头里会存储着此对象偏向的线程id的信息。一个线程获取某个对象的偏向锁的流程如下:

一个线程持有某个对象的偏向锁,并且受到竞争,偏向锁就有可能膨胀为轻量级锁,流程如下:

轻量级锁
轻量级锁由偏向锁膨胀而来,它的特点是获取轻量级锁失败的线程不会陷入阻塞。而是通过CAS的方式去获取锁,失败则重试,再次进行CAS操作去获取锁,也称自旋。CAS是一个原子操作,以后再总结。
如果是一个线程以及获得了某个对象的轻量级锁,还被其他线程不断竞争,轻量级锁就会膨胀为重量级锁。
获取轻量级锁的过程如下:

大概就是: 线程p的栈中有一块空间local record专门存放以经获取到的对象锁的信息。首先,将要目标对象的mark word拷贝进local record;然后对象的mark word部分就变为一个指针,指向displaced空间,更新锁标志、状态; 最后把local record的 owner 指针指向目标对象,表明已经获得这个对象的锁了。解锁,就是上述过程的反向操作。当然,这些操作是CAS方式进行的。
重量级锁
重量级锁是彻底的悲观锁,当一个线程获取某个对象的重量级锁失败时,线程便会阻塞,进入锁定池,等待这个锁被释放。当一个对象的锁变成了重量级锁,mark word便会成为一个指向 Mutex Lock(互斥量)的指针。
同步机制之一--Synchronized,以及此机制下的锁的本质和种类的更多相关文章
- Synchronized机制下偏向锁、轻量级锁、重量级锁的适用场景
上次总结了Synchronized机制下的锁的种类和原理,这次总结一下几种锁的适用场景. 偏向锁 一个线程获取某个对象的偏向锁的成本是很低的,只需把对象头的偏向线程id改为自己就好,如果偏向线程id已 ...
- java 多线程:线程通信-等待通知机制wait和notify方法;(同步代码块synchronized和while循环相互嵌套的差异);管道通信:PipedInputStream;PipedOutputStream;PipedWriter; PipedReader
1.等待通知机制: 等待通知机制的原理和厨师与服务员的关系很相似: 1,厨师做完一道菜的时间不确定,所以厨师将菜品放到"菜品传递台"上的时间不确定 2,服务员什么时候可以取到菜,必 ...
- JVM锁机制之synchronized
概述: synchronized是java用于处理多线程同步的一个关键字,用于标记一个方法/代码块,使之成为同步方法/同步块. 用synchronized可以避免多线程处理时的竞态条件问题. 相关概念 ...
- (转载)JVM实现synchronized的底层机制
目前在Java中存在两种锁机制:synchronized和Lock,Lock接口及其实现类是JDK5增加的内容,其作者是大名鼎鼎的并发专家Doug Lea.本文并不比较synchronized与Loc ...
- [转帖]B4. Concurrent JVM 锁机制(synchronized)
B4. Concurrent JVM 锁机制(synchronized) https://www.cnblogs.com/zlxyt/p/11050346.html 挺好的 感觉这个文章写的 不过想要 ...
- 并发编程的锁机制:synchronized和lock
1. 锁的种类 锁的种类有很多,包括:自旋锁.自旋锁的其他种类.阻塞锁.可重入锁.读写锁.互斥锁.悲观锁.乐观锁.公平锁.可重入锁等等,其余就不列出了.我们重点看如下几种:可重入锁.读写锁.可中断锁. ...
- java ->多线程_线程同步、死锁、等待唤醒机制
线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的. l 我们通过一个案例,演示线 ...
- java面试-synchronized底层实现机制
一.synchronized的三种应用方式 1.修饰实例方法,锁是当前实例对象,进入同步代码前要获得当前实例的锁 /** * synchronized修饰实例方法,当前线程的锁是实例对象account ...
- C#中的WinForm的消息机制简述,及消息机制下Invoke,和BeginInvoke的使用和区别
在Invoke或者BeginInvoke的使用中无一例外地使用了委托Delegate,至于委托的本质请参考我的另一随笔:对.net事件的看法. 一.为什么Control类提供了Invoke和Begin ...
随机推荐
- gRPC in ASP.NET Core 3.0 -- Protocol Buffer(1)
现如今微服务很流行,而微服务很有可能是使用不同语言进行构建的.而微服务之间通常需要相互通信,所以微服务之间必须在以下几个方面达成共识: 需要使用某种API 数据格式 错误的模式 负载均衡 ... 现在 ...
- WebGL着色器32位浮点数精度损失问题
问题 WebGL浮点数精度最大的问题是就是因为js是64位精度的,js往着色器里面穿的时候只能是32位浮点数,有效数是8位,精度丢失比较严重. 这篇文章里讲了一些处理方式,但是视坐标这种方式放在我们的 ...
- Heap Greedy
1 239 Sliding Window Maximun 双端队列 public int[] maxSlidingWindow(int[] nums, int k) { if (nums == nul ...
- 保存MTLAB图片是想去掉白边
在做一些matlab小实验的时候,生成的图片需要临时保存的时候会有多余的白边,如何能解决这种问题? 输入 iptsetpref('ImshowBorder','tight'); 后,再show一次图即 ...
- powershell小脚本--批量添加用户属性----导出登录时间
需求1:某公司所有员工少了MAIL属性,需要批量添加.例如,用户chenyy 添加邮件属性chenyy@xxxx.com 先导出(只导出名字)备用: Get-ADUser -Filter * -Pr ...
- Jenkins Java 反序列化远程执行代码漏洞(CVE-2017-1000353)
Jenkins Java 反序列化远程执行代码漏洞(CVE-2017-1000353) 一.漏洞描述 该漏洞存在于使用HTTP协议的双向通信通道的具体实现代码中,jenkins利用此通道来接收命令,恶 ...
- spring-boot项目的docker集成化部署(一)
目录 spring-boot项目的docker集成化部署 前言 基本思路与方案 基本步骤 准备源码 服务器和基础环境 结语 1. 本文总结: 2. 后期优化: spring-boot项目的docker ...
- HBase MapReduce 一些 ClassNotFoundException 所缺少的jar包
我们在用 java 操作 HBase 时,可能会出现相关的 ClassNotFoundException 等异常信息,但是我们又不想把 HBase lib 下的所有jar包全部导入到工程,因为会有 ...
- Vue小事例
login <!DOCTYPE html><html lang="ZH-cn"> <head> <meta charset="U ...
- 给面试官讲明白:一致性Hash的原理和实践
"一致性hash的设计初衷是解决分布式缓存问题,它不仅能起到hash作用,还可以在服务器宕机时,尽量少地迁移数据.因此被广泛用于状态服务的路由功能" 01分布式系统的路由算法 假设 ...