1、是一个重量级锁
对于普通方法,锁的是当前对象;
对于静态同步方法,锁的是当前类的class 对象;
对于同步方法块,锁的是Synchronized括号里配置对象;
2、synchronized用的锁存在于Java对象头里面:
Java对象头包含:MarkWord,Class Metadata Address,ArrayLength;
MarkWord:存储对象的hashcode或者锁信息(默认的是 hashcode,分带年龄,锁标记位);
Class Mata Address:存储到对象类型数据的指针;
ArrayLength:数组的 长度,如果当前对象是数组;
3、锁的升级与对比:
锁一共有四种状态:无锁状态,偏向锁,轻量级锁,重量级锁:
(1)偏向锁: 在大多数情况下,锁不存在多线程竞争,但是如果是正常的锁,每次获取锁的时候都会去对象头中
进行cas操作来枷锁和解锁,偏向锁则会在对象头和栈帧中 存储偏向锁id,以后线程获取的时候只需要查看时
候有这个id,有就获取,没有对markword总偏向锁的标识设置成1,如果没有设置偏向锁标志,再进行cas;
-XX:BiasedLockingStartupDelay=0;激活的时候关闭延迟;
-XX:UseBiasedLocking=false 关闭偏向锁;
(2)轻量级锁:线程再执行同步快的时候,jvm会在当前栈帧中创建锁的记录控件并将对象的markword复制过来,然后线程尝试使用cas将对象头中的markWord替换为指向锁记录的指针,如果成功就获取锁,如果失败,表示其他线程竞争,当前线程会尝试自旋来获取锁,如果旋转之后还是不能获取锁,则会将线程转化为重量级锁。
(3)重量级锁:当此线程获取锁时,其他线程等待;
优缺点:
偏向锁:加锁和解锁不需要额外的开销,如果存在竞争,会带来额外的撤销消耗,适用于只有一个线程来访问同步块;
轻量级锁:竞争的线程不会阻塞,提高了线程的响应速度,其他线程始终得不到锁,自旋会消耗CPU,适用于追求响应时间,同步块执行速度非常快
重量级锁:线程不使用自旋,不消耗cpu,线程会阻塞,响应时间慢,追求吞吐量,同步块执行时间长;’