码迷,mamicode.com
首页 > 其他好文 > 详细

浅析Synchronized

时间:2018-08-18 20:36:53      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:tor   编译   sync   mon   print   ===   null   的区别   name   

Synchronized的作用方式:

  • 作用于代码块
  • 作用于实例方法
  • 作用于静态方法
  • 作用于对象

1. 同步代码块和同步实例方法的区别:只有进入同步代码块才会锁住对象,而进入同步方法立即锁住对象。

public void print(){
    System.out.print("进入方法+线程:" + Thread.currentThread.getName());
    Synchronized(obj){
        while(true){}
    }
}

public synchronized void print(){
    System.out.print("进入方法+线程:" + Thread.currentThread.getName());
    while(true){}
}

线程A,B分别同时执行两个print()方法的结果:

进入方法+线程1
进入方法+线程2
===================
进入方法+线程1

 

2. 同步实例方法锁住对象,同步静态方法和同步类一样锁住class对象

3.JVM内部实现

  对于同步代码块:需要jvm和编译器配合实现。JVM指令集中有monitorenter和monitorexit指令支持synchronized关键字,monitorenter插入到同步代码块开始的地方,monitorexit插入到同步代码块结束的地方,编译器保证每一条monitorenter指令都必须执行对应的monitorexit指令,为了保证方法异常完成时,monitorenter和monitorexit依然正确配对执行,编译器自动产生一个异常处理器,这个异常处理器处理所有异常,目的就是用来执行monitorexit指令。任何对象都有一个monitor与之关联,monitor内部有一个owner字段,初始为null,保存持有该monitor的线程唯一标识。当进入同步时,线程都要尝试获取monitor。

  对于同步方法:无需通过字节码指令控制,实现在方法调用和返回的操作中。JVM从方法常量池的方法表结构中的ACC_SYNCHRONIZED访问标志得知一个方法是否声明为同步方法。当方法调用时,调用指令会检查方法的ACC_SYNCHRONIZED访问标志是否被设置,如果设置了,执行线程就要求先成功持有管程,然后才能执行方法,当方法退出(正常/抛出异常)时,释放管程。

 

浅析Synchronized

标签:tor   编译   sync   mon   print   ===   null   的区别   name   

原文地址:https://www.cnblogs.com/walker993/p/9498486.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!