java并发编程实战-14-15-synchronized----引申知识偏向锁和轻量级锁------二周目

synchronized:

     内置锁:每一个对象都可以用来成为锁,就是内置锁。

     synchronized方法上就是当前的this对象当前类的实例。

     synchronized修饰 普通方法  静态方法 (当前的class字节码对象)  修饰代码块(括号里面的对象或者类的字节码对象)。     

--------------------------t4-----------------理论-----------------------

 同步代码块其实是基于进入和退出Monitor对象,同步方法其实也可以用这个实现。

                // monitorenter
		synchronized (Sequence.class) {
			
			if(value > 0) {
				return value;
			} else {
				return -1;
			}
			
		}
		// monitorexit

 如何看字节码:

  1.首先进入t3

  2.javap -verbose XXX.class

  3.

  --------------

  锁存在哪里?

  任何一个对象都有一个monitor与之关联。被持有之后就在锁定的状态的。

  存在对象头中(书上写的)MARKWORD里面,任何对象都有一个monitor与之关联,被线程持有就处于锁定状态。

  数组和非数组。

  对象头(两个字节,数组是三个字节)中的信息:

  Mark Word:存对象的hashcode值(这个也是存在对象头里面的)和锁信息 ,分代年龄段。 

  Class Metadata Adsress(指向类型的地址)

  数组:ArrayLength数组长度

 -------------

锁的级别和轻重:无锁 偏向锁 轻量级锁 重量级锁

--------------

 偏向锁:锁是一个线程多次获得

 当一个线程访问同步块获得锁时候,会在对象头和栈帧中的锁记录里储存偏向线程的ID。

 再次进入的话找有没有这个偏向锁,如果失败则:

 测试是否是偏向锁(判断锁的标志位):

 是:尝试cas将对象头的偏向锁指向当前的线程

 否:cas竞争锁

 偏向锁:获取锁和释放锁会浪费资源。很多情况竞争锁不是多个线程而是一个线程不断的重入的。

   MarkWord:线程的id和锁的标志位是否是偏向锁。

  撤销:等竞争出现才释放锁。只有一个线程访问同步代码块的情景。

--------------

 轻量级锁

  加锁:线程在执行同步块之前,JVM会现在当前线程的栈帧中创建用于储存锁记录的空间,并将对象头的Mark Word复制到锁记录中。然后尝试cas将对象头的MarkWord替换为指向锁记录的指针。 成功:获得锁 失败:自旋获取锁。

  解锁:复制的东西替换回对象头,失败,表示当前锁存在竞争,则膨胀为重量级锁。不会降级。

--------------------------t4-----------------jvm层面------

注:MarkWord的详解https://blog.csdn.net/dufufd/article/details/81985236

----------------

偏向锁:竞争少的情况下,单线程,惰性释放,对象头和栈帧的锁记录里存储偏向的线程的ID。

轻量级锁:在执行同步块之前在当前线程的栈帧中创建存储锁记录的空间,并将对象头的MarkWord复制到锁记录中(修改)。释放锁失败膨胀为重量级锁,重量级锁不会恢复到轻量级锁。

偏向锁:只有一个线程访问。

轻量级锁:追求响应时间,同步块执行速度快的的时候。

重量级锁:最求吞吐量,同步块执行时间长的时候。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值