Java锁

乐观锁和悲观锁:

悲观锁: 认为自己在使用的数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁,确保数据不会被别的线索修改。synchronized关键字和Lock的实现类都是悲观锁 显式的锁定之后再操作同步资源
乐观锁: 乐观锁认为自己在使用的数据时不会有别的线程修复数据,所以不会添加锁,只是在更新数据的时候去判断之前有没有别的线程更新这个数据
如果这个数据没有被更新,当前线程将自己修改的数据成功写入。如果数据已经被其他线程更新,则根据不同的实现方式执行不同的操作。
乐观锁在Java中通常使用无锁编程来实现,最常见的是CAS算法,JAVA原子类的递增就是通过CAS自选锁实现的

适合读操作多的场景,不加锁的特点能够使其读操作的性能大幅提升。
乐观锁则直接去操作同步资源,是一种无锁算法,得之我幸不得我命,再抢
乐观锁一般有两种实现方式:
1.采用版本号机制
2.CAS(Compare-and-Swap,即比较并替换)算法实现

JVM中对应的锁在哪里?
在这里插入图片描述
synchronized有三种应用方式
1.作用于实例方法,当前实例加锁,进入同步代码前要获得当前实例的锁;
2.作用于代码块,对括号里配置的对象加锁
3.作用于静态方法,当前类加锁,进去同步代码前要获得当前类对象的锁

从字节码角度分析synchronized实现

怎么看?

javap -c ***.class文件反编译

-c 对代码进行反汇编
假如你需要更多信息 :
javap -v ***.class 文件反编译
-v -verbose 输出附加信息(包括行号、本地变量表,反汇编等详细信息)

synchronized同步代码块
javap -c ***.class文件反编译
在这里插入图片描述
在这里插入图片描述
结论: 实现使用的是monitorenter和monitorexit指令

一定是一个enter两个exit吗? 防止异常的的情况不能释放锁

在这里插入图片描述
如果是写了异常,则是1:1 两个athrow

synchronized普通同步方法
javap -v ***.class文件反编译
在这里插入图片描述
调用执行会检测方法的ACC_SYNCHRONIZED访问标识是否被设置、如果设置了,执行线程会将先持有的monitor然后
再执行方法,最后在方法完成,(无论是正常完成还是非正常完成)时释放monitor

synchronized静态同步方法

javap -v ***.class文件反编译

在这里插入图片描述

ACC_STATIC, ACC_SYNCHRONIZED访问标志区分该方法是否静态同步方法

反编译synchronized锁的是什么

为什么任何一个对象都可以成为一个锁?

管程 (英语:Monitors,也称为监视器) 是一种程序结构,结构内的多个子程序(对象或模块)形成的多个工作线程互斥访问共享资源。
这些共享资源一般是硬件设备或一群变量。对共享变量能够进行的所有操作集中在一个模块中。(把信号量及其操作原语“封装”在一个对象内部)管程实现了在一个时间点,最多只有一个线程在执行管程的某个子程序。管程提供了一种机制,管程可以看做一个软件模块,它是将共享的变量和对于这些共享变量的操作封装起来,形成一个具有一定接口的功能模块,进程可以调用管程来实现进程级别的并发控制。

在这里插入图片描述
在HotSpot虚拟机中,monitor采用ObjectMonitor实现

上述C++源码解读
ObjectMonitor.java→ObjectMonitor.cpp→objectMonitor.hpp

在这里插入图片描述
每个对象天生都带着一个对象监视器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值