一、Monitor
在理解monitor之前,先来了解一下Java对象头:
对象头
对象头是java中对象都具有的属性,是jvm在编译和运行阶段读取的信息。对象头包含三个部分:
- mark word
- 指针向类的指针
- 数组的长度(只有数组的对象用到)
以32位虚拟机为例:
1.概念
Monitor 被翻译为监视器或管程,可以理解为一个同步工具或一种同步机制,通常被描述为一个对象。每一个Java对象就有一把看不见的锁(C语言实现),称为内部锁或者Monitor锁。如果使用 synchronized给对象上锁(重量级)之后,该对象头的Mark Word 中就被设置指向 Monitor 对象的指针
1.monitor结构如下
Owner: 当前持有monitor的线程
EntryList:等待锁block状态的线程队列
WaitSet:处于wait状态的线程队列,即调用wait()方法的线程
- 刚开始 Monitor 中 Owner 为 null。
- 当 Thread-2 执行 synchronized(obj) 就会将 Monitor 的所有者 Owner 置为Thread-2,Monitor中只能有一个 Owner。
- 在 Thread-2 上锁的过程中,如果 Thread-3,Thread-4,Thread-5 也来执行 synchronized(obj),就会进入EntryList,处于BLOCKED状态。
- Thread-2 执行完同步代码块的内容,然后唤醒 EntryList 中等待的线程来竞争锁,竞争时是非公平的。
- 图中 WaitSet 中的 Thread-0,Thread-1 是之前获得过锁,调用了wait()方法的线程。
二、Synchronized 原理
jdk 1.6以前synchronized 关键字只表示重量级锁,1.6之后区分为偏向锁、轻量级锁、重量级锁。
1.无锁
无锁没有对资源进行锁定,所有的线程都能访问并修改同一个资源,但同时只有一个线程能修改成功。