反编译字节码角度分析synchronized关键字的原理
1.synchronized介绍
synchronized是java关键字。JVM规范中,synchronized关键字用于在线程并发执行时,保证同一时刻,只有一个线程可以执行某个代码块或方法;同时还保证了代码在执行完后所修改的数据对其它线程是可见的。总结来说:synchronized解决了并发编程安全问题的原子性,可见性,顺序行。Java中每一个对象都可以作为锁(monitor),这是synchronized实现同步的基础。synchronized作用于每一个对象时,要求占有当前对象的锁要么没有任何线程占用,或者是当前线程占用,这样该线程才能获得该对象的访问权,一旦某个线程获得对象的访问权,其它线程就会因为无法获得访问权限而进入阻塞状态。synchronized可用于3种情况:
(1)普通同步方法(实例方法),锁是当前实例对象 ,进入同步代码前要获得当前实例的锁
(2)静态同步方法,锁是当前类的Class对象 ,进入同步代码前要获得当前类的Class对象的锁
(3)同步方法块,锁是括号里面的对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。
那么就以这3种情况分析下反编译后得字节码,看看有synchronized修饰的代码块有何不同之处
2.反编译字节码分析synchronized
下面是含有3中情况的一个demo源码
public class TestSynchornize {
/**
* 修饰静态方法
*/
public synchronized static void test1() {
System.out.println("test1");
}
/**
* 修饰实例方法
*/
public synchronized void test2(){
System.out.println("test2");
}
/**
* 修饰代码块
*/
public void test3(){
synchronized (this){
System.out.println("test3");
}
}
}
用 javap 命令反编译字节码TestSynchornize.class,截图三种情况字节码如下:
静态方法

实例方法

代码块

(1)首先,可以看到在反编译代码块那里的字节码中可以看到其中有一个monitorenter指令和两个monitorexit指令。其实这就是synchronized的关键所在,synchronized修饰的代码块会带有monitorenter和monitorexit指令,用于jvm中控制同步代码块访问时必须获得对象锁。那么这里为啥会有两个monitorexit指令,获取对象锁执行完代码后不是释放对象锁就行了吗?按理来说monitorenter和monitorexit应该是一对一的?这里就是关键所在,JVM为了防止异常,获得锁的线程无法释放的情况,规定了synchronized锁修饰的代码块当线程执行异常时,会自动释放对象锁。因此这里有两个monitorexit指令,分别对应正常释放和异常释放。
(2)可以看到在修饰静态方法和实例方法那里并没有monitorenter和monitorexit指令。但是可以观察到在方法的访问flags那里都有ACC_SYNCHRONIZED修饰。其实这里也是会用到monitorenter和monitorexit,只不过在修饰方法时用ACC_SYNCHRONIZED代替了。再加上ACC_STATIC就可以判断是静态方法还是实例方法了,后面拿到需要获取的所对象,实现方式就跟代码块那里一样了。
3.总结
synchronized之所以是JVM层实现的同步控制的,原因在于代码编译中就加入了monitorenter和monitorexit指令控制同步访问,各个JVM厂商按照jvm规范实现该指令。
注意:本文仅代表个人理解和看法哟!和本人所在公司和团体无任何关系!
反编译字节码角度分析synchronized关键字的原理的更多相关文章
- 【synchronized锁】通过synchronized锁 反编译查看字节码指令分析synchronized关键字修饰方法与代码块的区别
前提: 首先要铺垫几个前置的知识: Java中的锁如sychronize锁是对象锁,Java对象头中具有标识位,当对象锁升级为重量级锁时,重量级锁的标识位会指向监视器monitor, 而每个Java对 ...
- 从字节码角度分析Byte类型变量b++和++b
1. 下面是一到Java笔试题: public class Test2 { public void add(Byte b) { b = b++; } public void test() { Byte ...
- IDEA设置External Tools之Javap反编译字节码
通过Jdk的命令javap可以反编译查看字节码,但是在使用idea的时候一直用命令行去操作不太好操作,而且因为idea会把class码 放在target里面,经常会忘记切换目录.这个时候idea的Ex ...
- 源码角度分析-newFixedThreadPool线程池导致的内存飙升问题
前言 使用无界队列的线程池会导致内存飙升吗?面试官经常会问这个问题,本文将基于源码,去分析newFixedThreadPool线程池导致的内存飙升问题,希望能加深大家的理解. (想自学习编程的小伙伴请 ...
- synchronized关键字所生成的字节码详细分析
在之前已经将如下这样的源文件对应的字节码文件完整的分析完了,如下: 这次再来写一个内容稍丰富一点的类,准备再来从头至尾的来分析一下,对其字节码的理解进一步巩固,如下: 然后用javap -verbos ...
- 从java字节码角度看线程安全性问题
先看代码: package com.roocon.thread.t3; public class Sequence { private int value; public int getNext(){ ...
- 自修改代码 on the fly 动态编译 即时编译 字节码
https://zh.wikipedia.org/wiki/自修改代码 自修改代码(Self-modifying code)是指程序在运行期间(Run time)修改自身指令.可能的用途有:病毒利用此 ...
- JAVA面试题 StringBuffer和StringBuilder的区别,从源码角度分析?
面试官Q1:请问StringBuffer和StringBuilder有什么区别? 这是一个老生常谈的话题,笔者前几年每次面试都会被问到,作为基础面试题,被问到的概率百分之八九十.下面我们从面试需要答到 ...
- mac 环境下Android 反编译源码
mac环境下Android 反编译 一.需要的工具 apktool:反编译APK文件,得到classes.dex文件,同时也能获取到资源文件以及布局文件. dex2jar:将反编译后的classes. ...
随机推荐
- 完全卸载win10上的Ubuntu子系统 - Windows Subsystem for Linux(WSL)
Ctrl + R 键入: lxrun /uninstall /full 具体请看 microsoft的说明:Frequently Asked Questions
- 不用 PS 和 AI,5个网站能做出更好看的设计
要完成漂亮的设计,一定要掌握 PS.AI.Sketch 等专业的做图工具才可以.其实,现在有很多网站可以帮助不会专业设计工具的我们,做出很多很漂亮的设计,完成自己的设计需求.今天,我们就来介绍一下这些 ...
- list采坑记录一下
List<Integer> cards = Lists.newArrayList(6,10,11,12,21,23,29,30,38,39,42,43,46,51,53,59,60);Li ...
- js-打印九九乘法表
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
有两种实现方法,分别是继承Thread类与实现Runnable接口用synchronized关键字修饰同步方法反对使用stop(),是因为它不安全.它会解除由线程获取的所有锁定,而且如果对象处于一种不 ...
- mysql通过表空间来恢复或者传递数据
mysql的备份工具通常有 mysqldump ,mysqlpump(5.7后新特性)等备份工具,这里我们可以尝试使用表空间进行传递 方式是:拷贝数据文件+拷贝表空间 对应innodb引擎就是 i ...
- Faster-RCNN论文精读
State-of-the-art object detection networks depend on region proposal algorithms to hypothesize objec ...
- Android中自己定义一个shade.xml
自己定义一个shade: <shape> <!-- 实心 --> <solid android:color="#ff9d77"/> <!- ...
- php获取网页源码分行显示
file(PHP 3, PHP 4 )file -- 把整个文件读入一个数组中说明:file ( string filename [, int use_include_path [, resource ...
- css定位的理解
在CSS中关于定位的内容是:position:relative | absolute | static | fixed ● static 没有特别的设定,遵循基本的定位规定,不能通过z-index进行 ...