Synchronized关键字

在这里插入图片描述

synchronized关键字是啥?

1 syn是通过给对象头加锁,就是设置对象头的锁状态的方式,用来控制线程同步的,可以用来修饰 方法 代码块 ,可以保证原子性,有序性,可见性,1.6之前syn是重量级锁,效率很低下,在1.6之后进行优化,比如说:锁消除,偏向锁,轻量级锁,重量级锁减小了锁操作的开销。
(代码块同步是使用monitorenter和monitorexit指令实现的,线程执行monitorenter指令时尝试获取monitor的所有权,monitorexit退出monitor,不再是这个monitor的所有者。其他被这个monitor阻塞的线程可以尝试去获取这个 monitor 的所有权。)
代码块的同步是通过使用monitorenter和monitorexit指令实现的,当线程执行monitorenter的时候就会尝试获取monitor的所有权,如果当前对象的monitor的进入计数器为0,就可以获取到这个对象锁,如果当前对象已经拥有了这个monitor的持有全,那么就可以重入这个monitor,重入的时候计数器也会加一。如果其他线程已经拥有了monitor的持有权,那么他就会阻塞,直到正在执行的线程执行完毕,即monitorexit指令执行,释放掉对象锁,并且把计数器设置为0.

方法的同步没有通过指令monitorenter和monitorexit来完成,而是通过ACC_SYNCHRONIZED标识符,放在常量池中。当方法调用的时候会检查方法的ACC_SYNCHRONIZED标识符是否已经被设置了,如果被设置了,执行的线程会先获取monitor,获取成功了才能执行方法体,方法执行完毕之后再释放monitor。在方法执行期间,任何其他线程都无法再获得同这个monitor对象。 其实和代码块本质上么有区别,只是方法同步是一种隐性的方式实现的,无需字节码来完成。

syn锁升级

在这里插入图片描述
偏向锁:在没有线程竞争的前提下,同一个线程多次获取同一把锁的时候,这个线程就没有必要每一次都进行cas操作,而是直接通过比较当前线程的threadID和对象头的ThreadId是否一致,一致的话就直接使用对象。
偏向锁的升级:如果不一致的话,就需要查看java对象头中记录的ThreadID是否还存活着,如果不存活了,锁对象就会被设置为无锁,这个线程就可以竞争其设置为偏向锁,如果存活着,就撤销偏向锁,升级为轻量级锁。
轻量级锁:轻量级锁考虑的是竞争锁的线程不多,并且线程持有锁的时间不长的情景下。就可以通过自旋一定的次数来获得这把锁,如果到达了一定的次数之后还没有获得这个锁,就会吧这把锁升级到重量级锁。
syn锁升级过程就是无锁 偏向锁 轻量级锁 重量级锁

偏向锁轻量级锁重量级锁的优缺点

在这里插入图片描述

锁粗化

因为加锁解锁也需要消耗资源,如果存在一系列的连续加锁解锁操作,就会导致不必要的性能损耗。所以就可以吧多个连续的加锁,解锁操作连接到一起,扩展成一个范围更大的锁,避免频繁的加锁解锁操作。

锁消除

Java虚拟机在JIT编译时(可以简单理解为当某段代码即将第一次被执行时进行编译,又称即时编译),通过对运行上下文的扫描,经过逃逸分析,去除不可能存在共享资源竞争的锁,通过这种方式消除没有必要的锁,可以节省毫无意义的请求锁时间

什么是自旋发生那个阶段

因为syn里的代码,执行速度非常快,此时如果等待的线程都进入阻塞态就是一种不值得的操作,因为线程的阻塞牵扯到用户态和内核态的切换,会消耗大量的资源,所以说我们不妨让等待锁的线程先不进入阻塞态,而是在syn的边界做循环,不断的尝试获取锁,这就是自旋。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值