背景
在java中,经常会用到synchronized关键字来保证线程安全,那么什么时候会存在线程安全呢?
- 共享数据的修改
- 临界资源访问
应用场景
- 修饰普通同步方法:锁
当前实例对象
; - 修饰静态同步方法:锁
当前的类Class对象
; - 修饰同步代码块:锁
Synchronized后面括号里配置的对象
,这个对象可以是任意对象;
synchronized原理
在绝大多数情况下,都只会有一个线程去访问synchronized修饰的代码块,所以synchronized在jdk1.6之后为了提升效率,优化了synchronized的机制,就是所谓的锁升级
。通过对象头
及ObjectMonitor
对象将锁划分了几个类型,其升级顺序为:无锁
->偏向锁
->轻量级锁
->重量级锁
,要了解它的原理,则必须要了解对象头。
对象头
java对象保存在内存中,由3个部分组成:
-
对象头
-
实例数据
-
对齐填充字节
这里,我们只对对象头加以说明
1、对象头的存在形式
JVM中的对象头有两种形式,它由三部分组成:
- Mark Word
- Klass Pointer(指向类的指针)
- 数组长度(只有数组对象才有)
1.1 普通对象
|--------------------------------------------------------------|
| Object Header (64 bits) |
|------------------------------------|-------------------------|
| Mark Word (32 bits) | Klass Word (32 bits) |
|------------------------------------|--------------