JVM005_synchronized、同步指令、管程、MESA

synchronized、同步指令、管程、MESA

synchronized是Java的一个关键词,可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,保证了原子性、可见性、有序性。

临界资源一次只能被一个线程访问的资源。

**临界区:**访问临界资源的那段代码。

synchronized的应用

synchronized可以修饰:

  1. 静态方法,锁定的是当前类的Class对象,进入同步代码前需要先获得当前类的锁。

    public class Test{public synchronized static int autoIncrement(int a){return a++;}
    }
    
  2. 实例方法,锁定的是当前实例对象,进入同步代码前需要先获得当前实例的锁。

    public class Test1{public synchronized int autoIncrement(int a){return a++;}
    }
    
  3. 代码块,锁定的是括号中的对象,进入同步代码前需要先获得指定对象的锁。

    public class Test2{public int autoIncrement(int a){// this 可以替换为任意指定对象synchronized(this){return a++; }}
    }
    

synchronized与编译

将上面的代码使用javac -g命令编译后,再利用javap -v命令进行汇编反编译,再截取我们关注内容可以的到如下内容:

 # 1修饰静态方法public static synchronized int autoIncrement(int);descriptor: (I)Iflags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED #  ACC_SYNCHRONIZED 访问标志区分一个方法是否同步方法Code:stack=1, locals=1, args_size=10: iload_01: iinc          0, 14: ireturnLineNumberTable:line 5: 0LocalVariableTable:Start  Length  Slot  Name   Signature0       5     0     a   I# 2修饰实例方法
public synchronized int autoIncrement(int);descriptor: (I)Iflags: ACC_PUBLIC, ACC_SYNCHRONIZED   #  ACC_SYNCHRONIZED 访问标志区分一个方法是否同步方法Code:stack=1, locals=2, args_size=20: iload_11: iinc          1, 14: ireturnLineNumberTable:line 5: 0LocalVariableTable:Start  Length  Slot  Name   Signature0       5     0  this   Lcom/lbc/springboot2/jvmlearn/Test1;0       5     1     a   I
# 3修饰代码块public int autoIncrement(int);descriptor: (I)Iflags: ACC_PUBLICCode:stack=2, locals=4, args_size=20: aload_01: dup2: astore_23: monitorenter  # 获取对象的锁,进入同步方法或同步块 -->>为什么虚拟机字节码指令表中说进入同步方法呢?4: iload_15: iinc          1, 18: aload_29: monitorexit   # 释放对象的锁,退出同步方法或同步块10: ireturn11: astore_312: aload_213: monitorexit	 # 释放对象的锁,退出同步方法或同步块14: aload_315: athrowException table:from    to  target type4    10    11   any11    14    11   anyLineNumberTable:line 6: 0line 7: 4line 8: 11

可以看到当synchronized修饰实例方法或者静态方法时,方法表集合中的方法访问标志都有ACC_SYNCHRONIZED,它表示该方法是synchronized的。而在synchronized修饰代码块是,javac编译后,会生成monitorentermonitorexit指令,分别表示获取对象的锁、进入同步块释放对象的锁、退出同步块

那么为什么会有两个monitorexit指令呢?第一个monitorexit是同步代码块正常执行完后释放锁,第二monitorexit表示有异常后,释放锁,保证不会因为异常导致无法释放锁。

– 待续

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/558752.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL————表维护相关低频操作总结

引言 一些对表结构的修改操作是日常数据库操作中非常低频的,这就好像盖完了一栋楼之后,很少会去动地基,不过这种情况在实际开发当中并非完全没有可能,因此,此篇博客主要总结表结构修改相关的语句。 一、备份表 如果…

JVM006_类加载的过程

类加载 类加载时机 类加载的过程 新术语 类加载器 简单的理解为将类转换为二进制流的类或接口。 数组的元素类型 数组去掉所有维度的类型。 数组的组件类型 数组去掉一个维度的类型。 基本块 按照控制流拆分的代码块。 1. 加载 加载是类加载过程的一个阶段。加载阶段主…

服务端开发——云服务器的端口转发设置(SSH隧道)

引言 本篇博客介绍端口转发的知识,并详细阐述操作和设置步骤。这是因为在实际工作中,会有很多企业从安全的角度考虑,为线上或重要的服务器设置一个跳板机(堡垒机),避免远程开发人员直接操作,是…

JVM007_运行时栈帧结构

运行时栈帧结构 执行引擎是JVM的核心组件之一。 所有Java虚拟机的执行引擎输入输出都是一致的:输入的是字节码二进制流,处理过程是字节码解析执行的等效过程,输出的是执行结果。 JVM以方法作为作基本的执行单元。“栈帧”是用于支持虚拟机进…

Shiro————核心设计思想

引言 以此篇博客为引,开启一个新的专栏分类——Shiro。 之前在工作中有比较快速的学习过Shiro安全框架,但经过一年的荒废,已经不是很熟悉了,通过这个系列,深入研究和学习Shiro的一些知识,填补安全管理方面…

Web应用安全————账号冻结与 Session 实时失效

引言 开篇时说些题外话,最近刚刚被公司CY,不过很快找到了下家,也同时拿到了三家公司的Offer。一周面试下来,总体感觉面试题少了,不过多了上机程序题。新公司是做外包,不过相比于上一家公司,也算…

Web应用安全————Shiro 解决会话固定漏洞

引言 承接上一篇《Web应用安全————账号冻结与 Session 实时失效》关于 session 的学习,本篇博客聚焦如何通过 shiro 解决会话固定导致的漏洞问题。 首先,没怎么接触过应用安全方面的小伙伴可能会发起疑问 - 什么是会话固定? 简单来说&…

Web应用安全————多点登录互斥

引言 在实际生活中,很多网站都做了多点登录互斥的操作,简单来说就是同一个账号,只能在一台电脑上登录,如果有人在其他地方登录,那么原来登录的地方就会自动下线,再进行操作就会弹出登录界面。 实现思路 …

Shiro————会话管理

引言 本篇博客翻译自Shiro 官方网站的 Session Manager 手册。 网页地址:http://shiro.apache.org/session-management.html Shiro 会话管理支持的特性 基于POJO/J2SE(IoC容器友好的)- Shiro 中的所有东西都是基于接口的,而且…

Linux进阶之路————磁盘查询

引言 承接《Linux进阶之路————Linux磁盘分区与挂载》,本文介绍实际生产中对于磁盘的监控和查询。 一、查询磁盘整体使用情况 基本语法: df -h 该命令会显示包括我们手动挂载的磁盘,如果使用 umount 卸载磁盘,那么将不会显示…

Linux进阶之路————CentOS网络配置

引言 Linux在装机后,如果没有特殊配置,会使用动态获取 IP 地址的策略。本文描述了,虚拟机使用网络的拓扑图,以及如何通过配置,将 IP 地址固定下来,不会因为重启而失效。同时可以访问外网地址。 一、NAT模…

Linux进阶之路————进程与服务管理

引言 在Linux 中,每个执行的程序(代码)都成为一个进程,Linux 为每一个进程分配了一个唯一的 id 号 - PID。 每个进程都会对应一个父进程,而这个父进程可以复制多个子进程,例如 www 服务器。 每个进程都可…

Linux进阶之路———— RPM 与 YUM 包管理

引言 rpm 是一种用于互联网下载的打包及安装工具,它包含在某些 Linux 发行版中,生成具有 .rpm 扩展名的文件。rpm 是 redhat package manager(RedHat 软件包管理器)的缩写,类似 Windows 下的 setup.exe 文件。这一文件…

Linux进阶之路———Shell 编程入门

引言 通过 Shell 编程的学习,铺平架构师道路上的一块大砖。 Shell 在Linux 系统中的定位如下所示: 一、第一个 Shell 脚本 我们通过一个简单的 Shell 脚本来感受一下。 在 Shell 中不需要加 “;” 结尾,通过 vim 可以进行 shell 的编程工…

Linux 实操———CentOS 6 安装配置 Oracle JDK 1.8

引言 本篇博客也属于Linux进阶系列,主要讲解如何在CentOS 6 下安装并配置 JDK 8。由于通过 yum 搜索的结果都是 openjdk,而目前企业中还是以 Oracle jdk 为主,因此,操作步骤这样的。 在Oracle 官网把 jdk 1.8 下载下来&#xff…

Linux 实操———CentOS 6 安装配置 Tomcat

引言 Linux下安装Tomcat。 一、下载、传输与解压 同《Linux 实操———CentOS 6 安装配置 Oracle JDK 1.8》一样,前期都是先在远程机上下载压缩包,然后通过远程终端,将压缩包放在 Linux 的 opt 目录下,然后解压。 下载地址是T…

Spring Boot 实用开发技巧————Eclipse 远程调试

引言 在之前的开发当中,都会进行本地项目启动,然后向本地服务发起请求来进行 Debug 调试代码,这也是开发人员最常见的调试操作。但是当项目逐渐成型,慢慢的将各个模块部署到服务器后,调试的手段可能就仅仅剩下查看执行…

Linux 实操———— Shell 远程执行命令

引言 目前,开发人员的部署方式是,将项目打包(Maven 打包) 然后将 生成的 jar 包等文件,通过Xshell 等终端工具手动传输到远程服务器上,然后再通过在终端执行远程服务器上的 shell 脚本来启动服务。 本篇博客聚焦这样一种解决方案…

Spring Boot 设置 ASCII banner 艺术字

引言 无意中看到Spring boot 项目的 resources 目录下有一个 banner.txt ,打开一看,居然是ASCII 字符画。于是兴起,简单研究了一下。 Spring boot 可以加载 resources 目录下的 banner.txt 文件,将字符画在启动之初输出到日志或…

MySQL 基础 ———— 分组查询

引言 承接上一篇《MySQL 基础 ————高频函数总结》,本篇单独针对分组查询进行简单的总结和归纳,并为后续更为复杂的DQL 语句做好铺垫。 查询语句: SELECT AVG(salary) FROM teacher; 实际上是以全表的 salary 字段来求平均值。但是在实…