通过sychronized给对象加锁,每个对象在实例化后,会同时实例出一个ObjectMoniter,同时对象有对象头(markOop
),在对象头中会存有当前锁状态信息,包含线程id。
ObjectMoniter
objectMonitor.hpp
ObjectMonitor() {
_header = NULL;
_count = 0;
_waiters = 0,
_recursions = 0;
_object = NULL;
_owner = NULL;
_WaitSet = NULL;
_WaitSetLock = 0 ;
_Responsible = NULL ;
_succ = NULL ;
_cxq = NULL ;
FreeNext = NULL ;
_EntryList = NULL ;
_SpinFreq = 0 ;
_SpinClock = 0 ;
OwnerIsThread = 0 ;
_previous_owner_tid = 0;
}
_count:当有对象获取锁,count+1,对象释放锁count-1
_EntryList:当有对象尝试获取锁,加入entryList中
_WaitSet:当调用wait方法,进入等待队列
_owner:拥有锁当线程,当锁释放是,count-1同时owner置为NULL
当使用sychronized给对象加锁时,字节码中是monitorenter给指定对象加锁,给静态方法加锁时,使用ACC_SYNCHRONIZED标志给当前对象加锁。
public class SychronizedTest {
private final Object lock = new Object();
private volatile int count;
public synchronized void method1() {
count++;
}
public void method2() {
synchronized (lock) {
count++;
}
}
}
bytecode
public synchronized void method1();
descriptor: ()V
flags: ACC_PUBLIC, ACC_SYNCHRONIZED
Code:
stack=3, locals=1, args_size=1
0: aload_0
1: dup
2: getfield #4 // Field count:I
5: iconst_1
6: iadd
7: putfield #4 // Field count:I
10: return
LineNumberTable:
line 14: 0
line 15: 10
LocalVariableTable:
Start Length Slot Name Signature
0 11 0 this Lcom/chao/SychronizedTest;
public void method2();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=3, locals=3, args_size=1
0: aload_0
1: getfield #3 // Field lock:Ljava/lang/Object;
4: dup
5: astore_1
6: monitorenter
7: aload_0
8: dup
9: getfield #4 // Field count:I
12: iconst_1
13: iadd
14: putfield #4 // Field count:I
17: aload_1
18: monitorexit
19: goto 27
22: astore_2
23: aload_1
24: monitorexit
25: aload_2
26: athrow
27: return
Exception table:
from to target type
7 19 22 any
22 25 22 any
LineNumberTable:
........
网友评论