前言
synchronized是Java中解决并发问题的常用方法,其主要作用如下:Reordering
基本使用
synchronized修改方法和代码块。让我们看一个简单的例子
publicclassSynTest{
公共无效锁测试(){
同步(这){
System.out.println(233);
}
}
}
使用javap-cSysTest.class反编译此代码
从“SynTest.java”编译
publicclasscom.happycode.lock.SynTest{
公众号快乐代码。锁。合成测试();
代码:
0:aload_0
1:invokespecial#1//方法java/lang/Object."":()V
4:返回
publicvoidlockTest();
代码:
0:aload_0
1:重复
2:astore_1
3:监控输入
4:getstatic#2//字段java/lang/System.out:Ljava/io/PrintStream;
7:西普什233
10:invokevirtual#3//方法java/io/PrintStream.println:(I)V
13:aload_1
14:监听退出
15:转到23
18:astore_2
19:aload_1
20:监听退出
21:aload_2
22:扔
23:返回
异常表:
从目标类型
41518任意
182118任意
} 我们需要注意的是monitorenter和monitorexit指令,这两个指令是jvm提供的。每个对象都有一个监视器锁(Monitor),当Monitor被占用时就会被锁定。monitorenter命令返回并尝试获取Monitor。如果Monitor的计数器为0,则表示获取成功,线程进入,Monitor计数器加1。如果不为0,则线程会被阻塞。也可以看出synchronized是不公平的。其实wait和notify也是依赖于monitor的Monitor。这就是为什么它们只能在同步块内。
