

作者 | JasonGaoH
来源 | juejin.im/post/5d439934e51d4561b416d3f2
synchronized 关键字
什么是 synchronized
Synchronized keyword enable a simple strategy for preventing thread interference and memory consistency errors: if an object is visible to more than one thread, all reads or writes to that object's variables ard done through synchronized methods.
synchronized 关键字提供了一种锁的机制,能够确保共享变量的互斥访问,从而防止数据不一致的问题出现 synchronized 关键字包括 monitor enter 和 monitor exit 两个 JVM 指令,它能够保证在任何时候任何线程执行到 monitor enter 成功之前都必须从主内存中获取数据,而不是缓存中,在 monitor exit 运行成功之后,共享变量被更新后的值必须刷入主内存 synchronized 的执行严格遵守 java happens-before 规则,一个 monitor exit 指令之前必定要有一个 monitor enter
synchronized 关键字的用法
同步方法
public synchronized void sync() {
//...
}
同步方法块
private final Object lock = new Object();
public void sync() {
synchronized(lock) {
//...
}
}
深入分析 synchronized 关键字
线程堆栈分析
import java.util.concurrent.TimeUnit;
public class TestSync {
private final static Object lock = new Object();
public void accessResource() {
synchronized(lock) {
try {
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
final TestSync sync = new TestSync();
for(int i =0;i<5;i++) {
new Thread(){
@Override
public void run() {
sync.accessResource();
}
}.start();
}
}
}

JVM 指令分析
Compiled from "TestSync.java"
public class main.TestSync {
static {};
Code:
0: new #3 // class java/lang/Object
3: dup
4: invokespecial #10 // Method java/lang/Object."<init>":()V
7: putstatic #13 // Field lock:Ljava/lang/Object;
10: return
public main.TestSync();
Code:
0: aload_0
1: invokespecial #10 // Method java/lang/Object."<init>":()V
4: return
public void accessResource();
Code:
0: getstatic #13 // Field lock:Ljava/lang/Object;
3: dup
4: astore_1
5: monitorenter
6: getstatic #20 // Field java/util/concurrent/TimeUnit.MINUTES:Ljava/util/concurrent/TimeUnit;
9: ldc2_w #26 // long 10l
12: invokevirtual #28 // Method java/util/concurrent/TimeUnit.sleep:(J)V
15: goto 23
18: astore_2
19: aload_2
20: invokevirtual #32 // Method java/lang/InterruptedException.printStackTrace:()V
23: aload_1
24: monitorexit
25: goto 31
28: aload_1
29: monitorexit
30: athrow
31: return
Exception table:
from to target type
6 15 18 Class java/lang/InterruptedException
6 25 28 any
28 30 28 any
public static void main(java.lang.String[]);
Code:
0: new #1 // class main/TestSync
3: dup
4: invokespecial #44 // Method "<init>":()V
7: astore_1
8: iconst_0
9: istore_2
10: goto 27
13: new #45 // class main/TestSync$1
16: dup
17: aload_1
18: invokespecial #47 // Method main/TestSync$1."<init>":(Lmain/TestSync;)V
21: invokevirtual #50 // Method main/TestSync$1.start:()V
24: iinc 2, 1
27: iload_2
28: iconst_5
29: if_icmplt 13
32: return
}
public void accessResource();
Code:
0: getstatic #13 //①获取lock
3: dup
4: astore_1
5: monitorenter //②执行monitorenter JVM指令
6: getstatic #20 // Field java/util/concurrent/TimeUnit.MINUTES:Ljava/util/concurrent/TimeUnit;
9: ldc2_w #26 // long 10l
12: invokevirtual #28 // Method java/util/concurrent/TimeUnit.sleep:(J)V
15: goto 23 //③跳转到23行
18: astore_2
19: aload_2
20: invokevirtual #32 // Method java/lang/InterruptedException.printStackTrace:()V
23: aload_1 //④
24: monitorexit //⑤ 执行monitor exit JVM指令
25: goto 31
28: aload_1
29: monitorexit
30: athrow
31: return
monitorenter
monitorexit
synchronized 的锁优化

文章转载自JavaFish,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




