java中synchronized关键字分析
今天我们来分析一下java中synchronized关键字。首先来看一段java代码:(本地编译环境为mac,jdk1.8的环境)
Demo.java
package com.example.springcloud.provider.demo;
public class Demo {
private boolean isOk = true;
public void test(){
isOk=false;
}
}
编译周后的Demo.class二进制文件:
Demo.class
cafe babe 0000 0034 0015 0a00 0400 1109
0003 0012 0700 1307 0014 0100 0469 734f
6b01 0001 5a01 0006 3c69 6e69 743e 0100
0328 2956 0100 0443 6f64 6501 000f 4c69
6e65 4e75 6d62 6572 5461 626c 6501 0012
4c6f 6361 6c56 6172 6961 626c 6554 6162
6c65 0100 0474 6869 7301 002c 4c63 6f6d
2f65 7861 6d70 6c65 2f73 7072 696e 6763
6c6f 7564 2f70 726f 7669 6465 722f 6465
6d6f 2f44 656d 6f3b 0100 0474 6573 7401
000a 536f 7572 6365 4669 6c65 0100 0944
656d 6f2e 6a61 7661 0c00 0700 080c 0005
0006 0100 2a63 6f6d 2f65 7861 6d70 6c65
2f73 7072 696e 6763 6c6f 7564 2f70 726f
7669 6465 722f 6465 6d6f 2f44 656d 6f01
0010 6a61 7661 2f6c 616e 672f 4f62 6a65
6374 0021 0003 0004 0000 0001 0002 0005
0006 0000 0002 0001 0007 0008 0001 0009
0000 0038 0002 0001 0000 000a 2ab7 0001
2a04 b500 02b1 0000 0002 000a 0000 000a
0002 0000 0003 0004 0004 000b 0000 000c
0001 0000 000a 000c 000d 0000 0001 000e
0008 0001 0009 0000 0034 0002 0001 0000
0006 2a03 b500 02b1 0000 0002 000a 0000
000a 0002 0000 0007 0005 0008 000b 0000
000c 0001 0000 0006 000c 000d 0000 0001
000f 0000 0002 0010
使用javap -v Demo.class > Demo.txt 文件得到反编译的汇编语言:
Demo.txt
Classfile /Users/shiwen/IdeaProjects/springcloud/example-springcloud-provider/target/classes/com/example/springcloud/provider/demo/Demo.class
Last modified 2017-10-11; size 424 bytes
MD5 checksum 1f57b26a93d1cc466ff58bcec5ff37fb
Compiled from "Demo.java"
public class com.example.springcloud.provider.demo.Demo
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #4.#17 // java/lang/Object."<init>":()V
#2 = Fieldref #3.#18 // com/example/springcloud/provider/demo/Demo.isOk:Z
#3 = Class #19 // com/example/springcloud/provider/demo/Demo
#4 = Class #20 // java/lang/Object
#5 = Utf8 isOk
#6 = Utf8 Z
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 Lcom/example/springcloud/provider/demo/Demo;
#14 = Utf8 test
#15 = Utf8 SourceFile
#16 = Utf8 Demo.java
#17 = NameAndType #7:#8 // "<init>":()V
#18 = NameAndType #5:#6 // isOk:Z
#19 = Utf8 com/example/springcloud/provider/demo/Demo
#20 = Utf8 java/lang/Object
{
public com.example.springcloud.provider.demo.Demo();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_1
6: putfield #2 // Field isOk:Z
9: return
LineNumberTable:
line 3: 0
line 4: 4
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this Lcom/example/springcloud/provider/demo/Demo; public void test();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: iconst_0
2: putfield #2 // Field isOk:Z
5: return
LineNumberTable:
line 7: 0
line 8: 5
LocalVariableTable:
Start Length Slot Name Signature
0 6 0 this Lcom/example/springcloud/provider/demo/Demo;
}
SourceFile: "Demo.java"
修改Demo.java文件在方法中新增synchronized如下:
package com.example.springcloud.provider.demo;
public class Demo {
private boolean isOk = true;
private synchronized void test(){
isOk=false;
} }
反编译为汇编后:(不同的地方用黄色标识出来了)
Classfile /Users/shiwen/IdeaProjects/springcloud/example-springcloud-provider/target/classes/com/example/springcloud/provider/demo/Demo.class
Last modified 2017-10-11; size 424 bytes
MD5 checksum 000d5f4eb139b3d12c483f7087c0c970
Compiled from "Demo.java"
public class com.example.springcloud.provider.demo.Demo
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #4.#17 // java/lang/Object."<init>":()V
#2 = Fieldref #3.#18 // com/example/springcloud/provider/demo/Demo.isOk:Z
#3 = Class #19 // com/example/springcloud/provider/demo/Demo
#4 = Class #20 // java/lang/Object
#5 = Utf8 isOk
#6 = Utf8 Z
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 Lcom/example/springcloud/provider/demo/Demo;
#14 = Utf8 test
#15 = Utf8 SourceFile
#16 = Utf8 Demo.java
#17 = NameAndType #7:#8 // "<init>":()V
#18 = NameAndType #5:#6 // isOk:Z
#19 = Utf8 com/example/springcloud/provider/demo/Demo
#20 = Utf8 java/lang/Object
{
public com.example.springcloud.provider.demo.Demo();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_1
6: putfield #2 // Field isOk:Z
9: return
LineNumberTable:
line 3: 0
line 4: 4
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this Lcom/example/springcloud/provider/demo/Demo; public synchronized void test();
descriptor: ()V
flags: ACC_PUBLIC, ACC_SYNCHRONIZED
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: iconst_0
2: putfield #2 // Field isOk:Z
5: return
LineNumberTable:
line 7: 0
line 8: 5
LocalVariableTable:
Start Length Slot Name Signature
0 6 0 this Lcom/example/springcloud/provider/demo/Demo;
}
SourceFile: "Demo.java"
改为synchronized代码块:
package com.example.springcloud.provider.demo;
public class Demo {
private boolean isOk = true;
public void test() {
synchronized (this) {
isOk = false;
}
}
}
反编译汇编为:
Classfile /Users/shiwen/IdeaProjects/springcloud/example-springcloud-provider/target/classes/com/example/springcloud/provider/demo/Demo.class
Last modified 2017-10-11; size 536 bytes
MD5 checksum 64305bd51f24f439444d9240efd483fd
Compiled from "Demo.java"
public class com.example.springcloud.provider.demo.Demo
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #4.#21 // java/lang/Object."<init>":()V
#2 = Fieldref #3.#22 // com/example/springcloud/provider/demo/Demo.isOk:Z
#3 = Class #23 // com/example/springcloud/provider/demo/Demo
#4 = Class #24 // java/lang/Object
#5 = Utf8 isOk
#6 = Utf8 Z
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 Lcom/example/springcloud/provider/demo/Demo;
#14 = Utf8 test
#15 = Utf8 StackMapTable
#16 = Class #23 // com/example/springcloud/provider/demo/Demo
#17 = Class #24 // java/lang/Object
#18 = Class #25 // java/lang/Throwable
#19 = Utf8 SourceFile
#20 = Utf8 Demo.java
#21 = NameAndType #7:#8 // "<init>":()V
#22 = NameAndType #5:#6 // isOk:Z
#23 = Utf8 com/example/springcloud/provider/demo/Demo
#24 = Utf8 java/lang/Object
#25 = Utf8 java/lang/Throwable
{
public com.example.springcloud.provider.demo.Demo();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_1
6: putfield #2 // Field isOk:Z
9: return
LineNumberTable:
line 3: 0
line 4: 4
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this Lcom/example/springcloud/provider/demo/Demo; public void test();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=1
0: aload_0
1: dup
2: astore_1
3: monitorenter
4: aload_0
5: iconst_0
6: putfield #2 // Field isOk:Z
9: aload_1
10: monitorexit
11: goto 19
14: astore_2
15: aload_1
16: monitorexit
17: aload_2
18: athrow
19: return
Exception table:
from to target type
4 11 14 any
14 17 14 any
LineNumberTable:
line 7: 0
line 8: 4
line 9: 9
line 10: 19
LocalVariableTable:
Start Length Slot Name Signature
0 20 0 this Lcom/example/springcloud/provider/demo/Demo;
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 14
locals = [ class com/example/springcloud/provider/demo/Demo, class java/lang/Object ]
stack = [ class java/lang/Throwable ]
frame_type = 250 /* chop */
offset_delta = 4
}
SourceFile: "Demo.java"
和synchronized方法对比如下:


给isOk增加volatile关键字后
Classfile /Users/shiwen/IdeaProjects/springcloud/example-springcloud-provider/target/classes/com/example/springcloud/provider/demo/Demo.class
Last modified 2017-10-11; size 536 bytes
MD5 checksum 8dc910b015c7d5af2feac29d19f519a1
Compiled from "Demo.java"
public class com.example.springcloud.provider.demo.Demo
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #4.#21 // java/lang/Object."<init>":()V
#2 = Fieldref #3.#22 // com/example/springcloud/provider/demo/Demo.isOk:Z
#3 = Class #23 // com/example/springcloud/provider/demo/Demo
#4 = Class #24 // java/lang/Object
#5 = Utf8 isOk
#6 = Utf8 Z
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 Lcom/example/springcloud/provider/demo/Demo;
#14 = Utf8 test
#15 = Utf8 StackMapTable
#16 = Class #23 // com/example/springcloud/provider/demo/Demo
#17 = Class #24 // java/lang/Object
#18 = Class #25 // java/lang/Throwable
#19 = Utf8 SourceFile
#20 = Utf8 Demo.java
#21 = NameAndType #7:#8 // "<init>":()V
#22 = NameAndType #5:#6 // isOk:Z
#23 = Utf8 com/example/springcloud/provider/demo/Demo
#24 = Utf8 java/lang/Object
#25 = Utf8 java/lang/Throwable
{
public volatile boolean isOk;
descriptor: Z
flags: ACC_PUBLIC, ACC_VOLATILE public com.example.springcloud.provider.demo.Demo();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_1
6: putfield #2 // Field isOk:Z
9: return
LineNumberTable:
line 3: 0
line 4: 4
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this Lcom/example/springcloud/provider/demo/Demo; public void test();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=1
0: aload_0
1: dup
2: astore_1
3: monitorenter
4: aload_0
5: iconst_0
6: putfield #2 // Field isOk:Z
9: aload_1
10: monitorexit
11: goto 19
14: astore_2
15: aload_1
16: monitorexit
17: aload_2
18: athrow
19: return
Exception table:
from to target type
4 11 14 any
14 17 14 any
LineNumberTable:
line 7: 0
line 8: 4
line 9: 9
line 10: 19
LocalVariableTable:
Start Length Slot Name Signature
0 20 0 this Lcom/example/springcloud/provider/demo/Demo;
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 14
locals = [ class com/example/springcloud/provider/demo/Demo, class java/lang/Object ]
stack = [ class java/lang/Throwable ]
frame_type = 250 /* chop */
offset_delta = 4
}
SourceFile: "Demo.java"
java中synchronized关键字分析的更多相关文章
- Java中synchronized关键字理解
好记性不如烂笔头~~ 并发编程中synchronized关键字的地位很重要,很多人都称它为重量级锁.利用synchronized实现同步的基础:Java中每一个对象都可以作为锁.具体表现为以下三种形式 ...
- java中synchronized关键字的用法
在java编程中,经常需要用到同步,而用得最多的也许是synchronized关键字了,下面看看这个关键字的用法. 因为synchronized关键字涉及到锁的概念,所以先来了解一些相关的锁知识. j ...
- Java关键字-----------------java中synchronized关键字的用法
在java编程中,经常需要用到同步,而用得最多的也许是synchronized关键字了,下面看看这个关键字的用法. 因为synchronized关键字涉及到锁的概念,所以先来了解一些相关的锁知识. j ...
- Java中synchronized关键字你知道多少
1.什么是synchronized 我们将其理解为同步锁,可以实现共享资源的同步访问,解决线程并发的安全问题.synchronize翻译成中文:同步,使同步.synchronized:已同步. 1.1 ...
- java中synchronized关键字基础-1
1.synchronized关键字简介 synchronized是java中的一个关键字,在中文中为同步,也被称之为'同步锁',以此来达到多线程并发访问时候的并发安全问题,可以用来修饰代码块.非静态方 ...
- Java的synchronized关键字:同步机制总结
JAVA中synchronized关键字能够作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块.搞清楚synchronized锁定的是哪个对象,就能帮助我们设计更安全的多线程程 ...
- 从分布式锁角度理解Java的synchronized关键字
分布式锁 分布式锁就以zookeeper为例,zookeeper是一个分布式系统的协调器,我们将其理解为一个文件系统,可以在zookeeper服务器中创建或删除文件夹或文件.设D为一个数据系统,不具备 ...
- java基础Synchronized关键字之对象锁
java中Synchronized关键字之对象锁 当有多个线程对一个共享数据进行操作时,需要注意多线程的安全问题. 多线程的同步机制对资源进行加锁,使得在同一个时间,只有一个线程可以进行操作,同 ...
- 【转】java中volatile关键字的含义
java中volatile关键字的含义 在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...
随机推荐
- webgl优化
浏览器支持: Mozilla Firefox 42,Google Chrome 46,Apple Safari 9.0,MS Internet Explorer 11,MS Edge 13 Safar ...
- JavaWeb在线电子相册springmvc
(一) 这学期上了一们叫做J2EE的选修课,本以为很水,没想到这个课这么烦气,最后大实验是一个springmvc的电子相册,做了两个周,终于完事了,姑且把这一篇叫做(一)吧 粗略看了一下啊,两个人的实 ...
- 关于maven环境变量的配置问题
开始使用“MAVEN_HOME”配置完环境变量后,在cmd中输入mvn -v提示不是内部命令,后直接在PATH 路径里面添加maven所在的位置+\bin,比如,maven的路径为E:\maven\a ...
- 【读书笔记】《Linux内核设计与实现》进程管理与进程调度
大学跟老师做嵌入式项目,写过I2C的设备驱动,但对Linux内核的了解也仅限于此.Android系统许多导致root的漏洞都是内核中的,研究起来很有趣,但看相关的分析文章总感觉隔着一层窗户纸,不能完全 ...
- HDU 2062:Subset sequence(思维)
Subset sequence Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
- PythonStudy——变量 Variable
变量 变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念.变量可以通过变量名访问.在指令式语言中,变量通常是可变的:但在纯函数式语言(如Haskell)中,变量可能是不可变(immutab ...
- Object.is()
- LiveBindings --- 把对象之间的属性绑定起来
有了 FireMonkey 框架,它不同于 VCL ,以往的数据感知控件不能放在它上面,所以 XE2 提供了 LiveBindings 功能作为替代方案.另外它也是个通用的基础设施,同样可用于传统的V ...
- windows下有个目录名称中间有空格 java读目录空格变成%20 处理方法
String path=Parameter.class.getResource("").getPath();//得到路径//String path=Parameter.class. ...
- problem: vue中获取动态元素高度
前言:始终要相信你能想到的解决方案,基本上都是可以用技术实现的... 解决方法就是在mounted中在this.$nextTick()去获取,如果没有获取到,不是写法错就是,元素没有绑定对地方,注意检 ...