06synchronized

synchronized的作用是实现线程间同步,它的工作是对同步代码块加锁,使得每一次只能有一个线程进入同步块,从而保证线程间安全性。

synchronized有三种用法:

  1. 指定加锁对象:对给定的对象加锁,进入同步代码块前要获得给定对象的锁。
  2. 直接作用于实例方法:相当于对当前实例加锁,进入同步代码块前要获得当前实例的锁。
  3. 直接作用于静态方法:相当于对当前类加锁,进入同步代码块前要获得当前类的锁

JVM基于进入和退出Monitor对象来实现方法同步和代码块同步。

monitorenter指令是在编译后插入到同步代码块的开始位置,而monitorexit是插入到方法结束处和异常处,JVM要保证每个monitorenter必须有对应的monitorexit与之配对。任何对象都有一个monitor与之关联,当且一个monitor被持有后,它将处于锁定状态。线程执行到monitorenter指令时,将会尝试获取对象所对应的monitor的所有权,即尝试获得对象的锁。

synchronized用的锁是存在Java对象头里的。

public class Synchronized {
      public static void main(String[] args) {
           // 对Synchronized Class对象进行加锁
           synchronized (Synchronized.class) {
           }
           // 静态同步方法,对Synchronized Class对象进行加锁
           m();
      }
      public static synchronized void m() {
      }
}

在Synchronized.class同级目录执行javap–v Synchronized.class部分相关输出

public static void main(java.lang.String[]);
       // 方法修饰符,表示:public staticflags: ACC_PUBLIC, ACC_STATIC
      Code:
           stack=2, locals=1, args_size=1
           0: ldc       #1  // class com/murdock/books/multithread/book/Synchronized
           2: dup 
           3: monitorenter  // monitorenter:监视器进入,获取锁
           4: monitorexit   // monitorexit:监视器退出,释放锁
           5: invokestatic  #16 // Method m:()V
           8: return
    public static synchronized void m();
    // 方法修饰符,表示: public static synchronized
    flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED
           Code:
                   stack=0, locals=0

对于同步块的实现使用了monitorenter和monitorexit指令,而同步方法则是依靠方法修饰符上的ACC_SYNCHRONIZED来完成的。无论采用哪种方式,其本质是对一个对象的监视器(monitor)进行获取,而这个获取过程是排他的,也就是同一时刻只能有一个线程获取到由synchronized所保护对象的监视器。

实时内容请关注微信公众号,公众号与博客同时更新:程序员星星

实时内容请关注微信公众号,公众号与博客同时更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值