前言
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。这就是为什么它们只能在同步块内。