Java锁相关及synchronized关键字


Java中锁的概念

自旋锁:为了不放弃CPU执行时间,循环的使用CAS技术对数据进行尝试更新,直至成功。

悲观锁:假定会发生并发冲突,同步所有共享数据的相关操作,从读书据就开始上锁。

乐观锁:假定没有冲突,在修改数据时如果发现数据和之前获取的不一致,则读取最新数据,然后重试修改。

独享锁(写):给资源加上写锁,线程可以修改资源,其它线程不能再加锁;(单写)

共享锁(读):给资源加上读锁后只能读不能改,其他线程也只能加读锁,不能加写锁;(多读)

可重入锁、不可重入锁:线程拿到一把锁之后,可以自由进入同一把锁同步的其他代码,则为可重入锁;否则是不可重入锁。

公平锁、非公平锁:争抢锁的顺序,如果是按先来后到,则为公平锁;否则是非公平锁。

 

Java中几种重要的锁的实现方式:synchronized、ReentrantLock、ReentrantReadWriteLock

 

同步关键字synchronized

属于最基本的线程通信机制,基于对象监视器实现的。

Java中的每个对象都与一个监视器相关联,一个线程可以锁定或解锁监视器。

一次只有一个线程可以锁定监视器。

试图锁定该监视器的其他线程都会被阻塞,直到他们可以获得该监视器上的锁定为止。

特性:可重入、独享锁、悲观锁

 

锁的范围:类锁、对象锁

JVM优化:锁消除、锁粗化

提示:同步关键字,不仅是实现同步,根据JVM规范还能保证可见性(读取最新内存数据,结束后写入主内存)

 

同步关键字加锁原理:

Java对象头:

  如果对象是数组类型,则虚拟机用3个Word(字宽)存储对象头,如果对象是非数组类型,则用2字宽存储对象头。在32位虚拟机中,一字宽等于四字节,即32bit。

运行期Mark World 根据锁的不同状态而可能的存储结构如下图:

    对象mark word里面 包含四种状态tag( 00 01 10 11 )
    01 无锁    00 轻量锁     10 重量锁    11 GC废弃

 

 

 同步关键字,优化内容(JDK1.6之后,即锁的升级过程):

  1.偏向锁,JVM默认开启,可以使用参数关闭(减少在无竞争情况,JVM资源消耗)

  2.出现两个及以上的线程争抢,则升级——>轻量级锁(CAS修改状态)
  3.线程CAS自旋一定次数之后,升级为重量级锁(对象的mark word 内部会保存一个监视器锁的一个地址)

锁升级过程示意图如下:

偏向锁示意图:

轻量级锁示意图:

重量级锁示意图:

Monitor构造如下图所示:

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM