java锁学习笔记

堆内存中对象存着三个模块:对象头,实例变量,填充数据

对象头:存储对象的hashcode,锁信息或分代年龄或GC标志,类型指针指向对象的类元数据,JVM通过这个指针确定该对象是         哪个类的实例信息

实例变量:存放类的属性数据信息,包括父类的属性信息

填充数据:由于虚拟机要求对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅是为了字节对齐

当一个线程需要运行同步方法,线程对应的monitor对象,对象头会记录锁标记,锁标记指向monitor,当这个线程执行完毕或者          抛出异常,对象头会将锁标记去掉

monitor对象中有_EntryList,_WaitSet,_Owner标志

        当多线程并发并访问同一个同步代码时,首先会进入_EntryList,当线程获取锁标记后,monitor中的_Owner记录此线程,并在monitor中的计数器执行递增计算(+1),代表锁定,其他线程在_EntryList中继续阻塞。若执行线程调用wait方法,则monitor中的计数器执行赋值为0计算,并将_Owner标记赋值为null,代表放弃锁,执行线程如_WaitSet中阻塞。若执行线程调用otiry/notifyAll方法,_WaitSet中的线程被唤醒,进入_EntryList中阻塞,等待获取锁标记。若执行线程的同步代码执行结束,同样会释放锁标记,monitor中的_Owner标记赋值为null,且计数器赋值为0

 

 锁的重入:

在java中,同步锁是可以重入的,只有同一个线程调用同步方法或执行同步代码块,对同一个对象加锁时才可重入

 

锁的种类:

Java中锁的种类大致分为偏向锁,自旋锁,轻量级锁,重量级锁。

锁的使用方式:先提供偏向锁,如果不满足的时候,升级为轻量级锁,再不满足,升级为重量级锁。自旋锁是一个

过渡状态,不是一种实际的锁类型。

偏向锁:

   是一种编译解释锁,如果代码不可能出现多线程并发争抢同一个锁的时候,jvm编译代码,解释执行的时候,会自动

放弃同步信息,清楚synchronized的同步代码结果。使用锁标记的形式记录锁状态。在Monitor中有变量

ACC_SYNCHRONIZED,当变量值使用的时候,代表偏向锁锁定,可以避免锁的争抢。

轻量级锁:

    过渡锁,当偏向锁不满足,也就是有多线程并发访问,锁定同一个对象的时候,先提升为轻量级锁。也是使用

标记ACC_SYNCHRONIZED标记记录的。ACC_UNSYNCHRONIZED标记记录未获取锁信息的线程。就是只有两个线程

争抢锁标记的时候,优先使用轻量级锁。两个线程也有可能出现重量级锁

重量级锁:synchronized

 自旋锁:

      是一个过渡锁,是偏向锁和轻量级锁的过渡。当获取锁的过程中,未获取到。为了提高效率,jvm自动执行

若干次空循环,再次申请锁,而不是进入阻塞状态的情况,称为自旋锁。自旋锁提高效率就是避免线程状态变更

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值