前言
synchronized是Java中解决并发问题的一种常用方法,它主要的作用如下
确保线程互斥的访问代码
保证变量的可见性
解决重排序
基本使用
synchronized可以修饰方法、代码块,下面看一个简单的例子
public class SynTest {public void lockTest() {synchronized (this) {System.out.println(233);}}}
对这段代码使用javap -c SysTest.class进行反编译
Compiled from "SynTest.java"
public class com.happycode.lock.SynTest {public com.happycode.lock.SynTest();Code:0: aload_01: invokespecial #1 Method java/lang/Object."<init>":()V4: returnpublic void lockTest();Code:0: aload_01: dup2: astore_13: monitorenter4: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;7: sipush 23310: invokevirtual #3 // Method java/io/PrintStream.println:(I)V13: aload_114: monitorexit15: goto 2318: astore_219: aload_120: monitorexit21: aload_222: athrow23: returnException table:from to target type4 15 18 any18 21 18 any}
我们需要关注的是monitorenter和monitorexit指令,这些是jvm提供的,每个对象有一个监视器锁(Monitor),当 Monitor 被占用时就会处于锁定状态。monitorenter指令回去尝试获取Monitor,如果Monitor的计数器为0,则获取成功,线程进入,Monitor计数器加1,如果不为0,线程就会阻塞。也能看出synchronized是非公平的。其实wait和notify也依赖监视器Monitor。这就是为什么他们只能在synchronized块里。

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




