Java并发多线程

java并发(四)偏向锁、轻量级锁、重量级锁

2018-06-24  本文已影响52人  黄金矿工00七

在jdk1.6之前,Monitor的实现完全是依靠操作系统内部的互斥锁,需要进行用户态和内核态的切换(运行在用户态下的程序不能直接访问操作系统内核数据结构和程序。当我们在系统中执行一个程序时,大部分时间是运行在用户态下的,在其需要操作系统帮助完成某些它没有权力和能力完成的工作时就会切换到内核态。 处于用户态执行时,进程所能访问的内存空间和对象受到限制,其所处于占有的处理机是可被抢占的 ; 而处于核心态执行中的进程,则能访问所有的内存空间和对象,且所占有的处理机是不允许被抢占的。) 在jdk1.6中,引入了新的概念:偏向锁、轻量级锁、重量级锁

从java锁的类型来说,阻塞对应的就是悲观锁,自旋对应的就是乐观锁。在java中乐观锁主要的实现方式就是CAS操作,我们来简单说一下CAS

CAS:一个CAS方法包含三个参数CAS(V,E,N)。V表示要更新的变量,E表示预期的值,N表示新值。只有当V的值等于E时,才会将V的值修改为N。如果V的值不等于E,说明已经被其他线程修改了,当前线程可以放弃此操作,也可以再次尝试次操作直至修改成功。基于这样的算法,CAS操作即使没有锁,也可以发现其他线程对当前线程的干扰(临界区值的修改),并进行恰当的处理。
额外引申技术点:volatile
上面说到当前线程可以发现其他线程对临界区数据的修改,这点可以使用volatile进行保证。volatile实现了JMM中的可见性。使得对临界区资源的修改可以马上被其他线程看到

synchronized用的锁是存在Java对象头里的。如果对象是数组类型,则虚拟机用3个字宽
(Word)存储对象头(也就是24个字节),如果对象是非数组类型,则用2字宽存储对象头(16个字节)。在64位虚拟机中,1字宽等于8字节,即64bit。

java对象头存储结构
markword数据的长度在32位和64位的虚拟机(未开启压缩指针)中分别为32bit和64bit,它的最后2bit是锁状态标志位,用来标记当前对象的状态,对象的所处的状态,决定了markword存储的内容(它会根据对象的状态复用自己的存储空间)
64位虚拟机在不同状态下markword结构如下图所示:JVM源码中是这么写的
markword存储结构
最后2bit是锁状态标志位,用来标记当前对象的状态,对象的所处的状态,决定了markword存储的内容,如下表所示:
图片.png

下面来详细说一下各种锁:

在《深入理解java虚拟机中》是这样说的,如果说轻量级锁是在无竞争的情况下使用CAS操作去消除同步使用的互斥量, 那偏向锁就是在无竞争的情况下把整个同步都消除掉, 连CAS操作都不做了。

上一篇 下一篇

猜你喜欢

热点阅读