悲观锁是就是悲观思想,即认为写多,遇到并发写的可能性高,每次去拿数据的时候都认为别人会修改,因此每次在读写数据的时候都会上锁,这样别人想读写这个数据就会block直到拿到锁。因为数据进行加锁,期间对该数据进行读写的其余线程都会进行等待。java
synchronized的重量级锁就是悲观锁。AQS框架下的锁则是先尝试cas乐观锁去获取锁,获取不到,才会转换为悲观锁,如RetreenLock。数据结构
乐观锁是一种乐观思想,即认为读多写少,遇到并发写的可能性低,每次去拿数据的时候都认为别人不会修改,因此不会上锁,可是在更新的时候会判断一下在此期间别人有没有去更新这个数据,采起在写时先读出当前版本号,而后加锁操做(比较跟上一次的版本号,若是同样则更新),若是失败则要重复读-比较-写的操做。因为数据没有进行加锁,期间该数据能够被其余线程进行读写操做。并发
java中的乐观锁基本都是经过CAS操做实现的,CAS是一种更新的原子操做,比较当前值跟传入值是否同样,同样则更新,不然失败。框架
synchronized的偏向锁和轻量级锁就是乐观锁。spa
在Java技术发展史上,最开始使用的是悲观锁,实践中发现使用悲观锁有不少缺点,因此又引入了乐观锁。操作系统
两种锁各有优缺点,读取频繁使用乐观锁(可是可能出现“脏”读),写入频繁使用悲观锁(上下文切换开销大,可是保证没有“脏”数据)。线程
synchronized的重量级锁就是悲观锁。指针
synchronized的偏向锁和轻量级锁就是乐观锁。对象
java的线程是映射到操做系统原生线程之上的,若是要阻塞或唤醒一个线程就须要操做系统介入。blog
须要在用户态与内核态之间切换,这种切换会消耗大量的系统资源,由于用户态与内核态都有各自专用的内存空间,专用的寄存器等,用户态切换至内核态须要传递给许多变量、参数给内核,内核也须要保护好用户态在切换时的一些寄存器值、变量等,以便内核态调用结束后切换回用户态继续工做。
markword是java对象数据结构中的一部分,对象的markword和java各类类型的锁密切相关。
markword数据的长度在32位和64位的虚拟机(未开启压缩指针)中分别为32bit和64bit,它的最后2bit是锁状态标志位,用来标记当前对象的状态,对象的所处的状态,决定了markword存储的内容,以下表所示
32位虚拟机在不一样状态下markword结构以下图所示
了解了markword结构,有助于了解java锁的加锁解锁过程。