并发专题-锁synchronize

synchronize
加锁实现了原子性(独占性,排他性)以及可见性
锁机制的两个特性
互斥性:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程中的协调机制,这样在同一时间只有一个线程对需同步的代码块(复合操作)进行访问。互斥性我们也往往称为操作的原子性。
可见性:必须确保在锁被释放之前,对共享变量所做的修改,对于随后获得该锁的另一个线程是可见的(即在获得锁时应获得最新共享变量的值),否则另一个线程可能是在本地缓存的某个副本上继续操作从而引起不一致。

Synchronize(A.class | object) 传入一个类的class对象或一个对象。注意: 多个线程必须公用同一个锁对象。 传入A.class时,传入的是这个类的Class对象(在类加载器加载时会 产生一个单例的Clazz对象)。因此Synchronize(this)要慎用,除非确定是单例。因此通常还不如使用Synchronize(“A”), 因为“A”字符串常量在常量池中只会有一个。
在 Java 中,每个对象都会有一个monitor监视器。这个对象其实就是 Java 对象的锁,通常会被称为“内置锁”或“对象锁”。类的对象可以有多个,所以每个对象有其独立的对象锁,互不干扰。

  1. 某一线程占有这个对象的时候,先查看monitor 的计数器是不是0,如果是0表示还没有线程占有这个锁,这个时候线程就会占有这个对象,并且对这个对象的monitor+1;如果不为0,表示这个线程已经被其他线程占有,此时这个线程等待。当持有锁的线程释放占有权的时候,monitor-1;
    2)同一线程可以对同一对象进行多次加锁,+1,+1,重入性
    3)在 Java 中,针对每个类也有一个锁,可以称为“类锁”,类锁实际上是通过对象锁实现的,即类的 Class 对象锁。每个类只有一个 Class 对象,所以每个类只有一个类锁

synchronize的原理分析
Jconsole jdk自带的工具,可以查看线程的状态
在这里插入图片描述
在这里插入图片描述

Jstack pid 打印pid对应服务的堆栈, 要看得懂内存堆栈,必须具备线程的基本知识,比如线程的5个状态。
通过使用Jconsole和jstack查看堆栈,我们可以验证,synchronize具有排他性。

Javap -V 文件名 反编译 -v把一些附加信息打印出来
1)下面查看代码块的加锁
monitorenter互斥的入口
在这里插入图片描述
monitorexit互斥的出口
有时一个Monitorenter会有两个monitorexit,这只能说明它有两个出口,一个正常出口,一个异常出口。

  1. 方法加锁
    ACC_SYNCHRONIZED表示是互斥的方法
    在这里插入图片描述

JDK对Synchronize锁的优化
JDK1.6以前,锁都是重量锁。
3、使用synchronized注意的问题
(1)与moniter关联的对象不能为空
(2)synchronized作用域太大
(3)不同的monitor企图锁相同的方法
(4)多个锁的交叉导致死锁

偏向锁
轻量级锁
重量级锁(等待时间长)
对象头与monitor
一个对象实例包含:对象头、实例变量、填充数据
在这里插入图片描述
对象头:加锁的基础
实例变量:
填充数据:

2个字:
hashCode的作用:HashSet
在这里插入图片描述
在这里插入图片描述

无锁状态:没有加锁
偏向锁:在对象第一次被某一线程占有的时候,写入线程号到对象头和栈帧的锁记录里,当有线程访问的时候,若是之前的同一线程,则先测试对象头里的线程是否和当前线程ID一致,一致便能获得锁;不一致就会去查看对象头里的偏向锁标志是否已经设置为1,没有设置便去设置,设置了,就尝试使用CAS将对象头额偏向锁指向当前线程。
很多次被第一次占有它的线程获取次数多,成功
CAS算法 compare and set(CAS)
与无锁状态时间非常接近
竞争不激烈的时候适用(只有一个线程访问同步代码块的时候)

轻量级锁:线程有交替适用,互斥性不是很强,CAS失败,锁标志位设置为00
重量级锁:强互斥,锁标志位设置为10,等待时间长

轻量级锁向重量级升级额过程,设计用户线程与核心线程的切换,非常耗时。因此轻量级锁会优先自旋来获取锁。
自旋:竞争失败的时候,不是马上升级锁,而是执行几次空循环5 10
锁消除:JIT在编译时将不必要的锁去掉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值