同步机制之一--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 ...
随机推荐
- java - 多态实现机制
Java提供了编译时多态和运行时多态两种多态机制.前者是通过方法重载实现的,后者是通过方法的覆盖实现的. 在方法覆盖中,子类可以覆盖父类的方法,因此同类的方法会在父类与子类中有着不同的表现形式. 在J ...
- Pinyin4j简单使用教程
Pinyin4j是一个流行的Java库,支持中文字符和拼音之间的转换,拼音输出格式可以定制,在项目中经常会遇到需求用户输入汉字后转换为拼音的场景,这时候Pinyin4j就可以派上用场 有自己私服的可以 ...
- cookbook_类与对象
1修改实例的字符串表示 可以通过定义__str__()和__repr__()方法来实现 class Pair: def __init__(self,x,y): self.x = x self.y = ...
- 动态规划_Cow Bowling_POJ-3176
The cows don't use actual bowling balls when they go bowling. They each take a number (in the range ...
- PHP与ECMAScript_2_数据类型
PHP ECMAScript 数据类型 基本:String.Integer.Float.Boolean 基本:String. Number. Boolean.NULL.undefined 复合:Arr ...
- 快速安装k8s,版本为1.13.8
利用rpm快速部署k8s #!/bin/bash #快速安装k8s #by love19791126 107420988@qq.com pwd=$(pwd) masteripaddr=#(ip a s ...
- AI中台——智能聊天机器人平台的架构与应用(分享实录)
内容来源:宜信技术学院第3期技术沙龙-线上直播|AI中台——智能聊天机器人平台 主讲人:宜信科技中心AI中台团队负责人王东 导读:随着“中台”战略的提出,目前宜信中台建设在思想理念及架构设计上都已经取 ...
- WTM 构建DotNetCore开源生态,坐而论道不如起而行之
作为一个8岁开始学习编程,至今40岁的老程序员,这辈子使用过无数种语言,从basic开始,到pascal, C, C++,到后来的 java, c#,perl,php,再到现在流行的python. 小 ...
- [系列] Go - chan 通道
目录 概述 声明 chan 写入 chan 读取 chan 关闭 chan 示例 推荐阅读 概述 原来分享基础语法的时候,还未分享过 chan 通道,这次把它补上. chan 可以理解为队列,遵循先进 ...
- Java编程基础阶段笔记 day 07 面向对象编程(上)
面向对象编程 笔记Notes 面向对象三条学习主线 面向过程 VS 面向对象 类和对象 创建对象例子 面向对象的内存分析 类的属性:成员变量 成员变量 VS 局部变量 类的方法 方法的重载 可变个 ...