java中synchronized关键字分析
Posted 得意莫骄傲,失意莫沮丧。
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中synchronized关键字分析相关的知识,希望对你有一定的参考价值。
今天我们来分析一下java中synchronized关键字。首先来看一段java代码:(本地编译环境为mac,jdk1.8的环境)
Demo.java
1 package com.example.springcloud.provider.demo; 2 3 public class Demo { 4 private boolean isOk = true; 5 6 public void test(){ 7 isOk=false; 8 } 9 }
编译周后的Demo.class二进制文件:
Demo.class
1 cafe babe 0000 0034 0015 0a00 0400 1109 2 0003 0012 0700 1307 0014 0100 0469 734f 3 6b01 0001 5a01 0006 3c69 6e69 743e 0100 4 0328 2956 0100 0443 6f64 6501 000f 4c69 5 6e65 4e75 6d62 6572 5461 626c 6501 0012 6 4c6f 6361 6c56 6172 6961 626c 6554 6162 7 6c65 0100 0474 6869 7301 002c 4c63 6f6d 8 2f65 7861 6d70 6c65 2f73 7072 696e 6763 9 6c6f 7564 2f70 726f 7669 6465 722f 6465 10 6d6f 2f44 656d 6f3b 0100 0474 6573 7401 11 000a 536f 7572 6365 4669 6c65 0100 0944 12 656d 6f2e 6a61 7661 0c00 0700 080c 0005 13 0006 0100 2a63 6f6d 2f65 7861 6d70 6c65 14 2f73 7072 696e 6763 6c6f 7564 2f70 726f 15 7669 6465 722f 6465 6d6f 2f44 656d 6f01 16 0010 6a61 7661 2f6c 616e 672f 4f62 6a65 17 6374 0021 0003 0004 0000 0001 0002 0005 18 0006 0000 0002 0001 0007 0008 0001 0009 19 0000 0038 0002 0001 0000 000a 2ab7 0001 20 2a04 b500 02b1 0000 0002 000a 0000 000a 21 0002 0000 0003 0004 0004 000b 0000 000c 22 0001 0000 000a 000c 000d 0000 0001 000e 23 0008 0001 0009 0000 0034 0002 0001 0000 24 0006 2a03 b500 02b1 0000 0002 000a 0000 25 000a 0002 0000 0007 0005 0008 000b 0000 26 000c 0001 0000 0006 000c 000d 0000 0001 27 000f 0000 0002 0010
使用javap -v Demo.class > Demo.txt 文件得到反编译的汇编语言:
Demo.txt
1 Classfile /Users/shiwen/IdeaProjects/springcloud/example-springcloud-provider/target/classes/com/example/springcloud/provider/demo/Demo.class 2 Last modified 2017-10-11; size 424 bytes 3 MD5 checksum 1f57b26a93d1cc466ff58bcec5ff37fb 4 Compiled from "Demo.java" 5 public class com.example.springcloud.provider.demo.Demo 6 minor version: 0 7 major version: 52 8 flags: ACC_PUBLIC, ACC_SUPER 9 Constant pool: 10 #1 = Methodref #4.#17 // java/lang/Object."<init>":()V 11 #2 = Fieldref #3.#18 // com/example/springcloud/provider/demo/Demo.isOk:Z 12 #3 = Class #19 // com/example/springcloud/provider/demo/Demo 13 #4 = Class #20 // java/lang/Object 14 #5 = Utf8 isOk 15 #6 = Utf8 Z 16 #7 = Utf8 <init> 17 #8 = Utf8 ()V 18 #9 = Utf8 Code 19 #10 = Utf8 LineNumberTable 20 #11 = Utf8 LocalVariableTable 21 #12 = Utf8 this 22 #13 = Utf8 Lcom/example/springcloud/provider/demo/Demo; 23 #14 = Utf8 test 24 #15 = Utf8 SourceFile 25 #16 = Utf8 Demo.java 26 #17 = NameAndType #7:#8 // "<init>":()V 27 #18 = NameAndType #5:#6 // isOk:Z 28 #19 = Utf8 com/example/springcloud/provider/demo/Demo 29 #20 = Utf8 java/lang/Object 30 { 31 public com.example.springcloud.provider.demo.Demo(); 32 descriptor: ()V 33 flags: ACC_PUBLIC 34 Code: 35 stack=2, locals=1, args_size=1 36 0: aload_0 37 1: invokespecial #1 // Method java/lang/Object."<init>":()V 38 4: aload_0 39 5: iconst_1 40 6: putfield #2 // Field isOk:Z 41 9: return 42 LineNumberTable: 43 line 3: 0 44 line 4: 4 45 LocalVariableTable: 46 Start Length Slot Name Signature 47 0 10 0 this Lcom/example/springcloud/provider/demo/Demo; 48 49 public void test(); 50 descriptor: ()V 51 flags: ACC_PUBLIC 52 Code: 53 stack=2, locals=1, args_size=1 54 0: aload_0 55 1: iconst_0 56 2: putfield #2 // Field isOk:Z 57 5: return 58 LineNumberTable: 59 line 7: 0 60 line 8: 5 61 LocalVariableTable: 62 Start Length Slot Name Signature 63 0 6 0 this Lcom/example/springcloud/provider/demo/Demo; 64 } 65 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;
} }
反编译为汇编后:(不同的地方用黄色标识出来了)
1 Classfile /Users/shiwen/IdeaProjects/springcloud/example-springcloud-provider/target/classes/com/example/springcloud/provider/demo/Demo.class 2 Last modified 2017-10-11; size 424 bytes 3 MD5 checksum 000d5f4eb139b3d12c483f7087c0c970 4 Compiled from "Demo.java" 5 public class com.example.springcloud.provider.demo.Demo 6 minor version: 0 7 major version: 52 8 flags: ACC_PUBLIC, ACC_SUPER 9 Constant pool: 10 #1 = Methodref #4.#17 // java/lang/Object."<init>":()V 11 #2 = Fieldref #3.#18 // com/example/springcloud/provider/demo/Demo.isOk:Z 12 #3 = Class #19 // com/example/springcloud/provider/demo/Demo 13 #4 = Class #20 // java/lang/Object 14 #5 = Utf8 isOk 15 #6 = Utf8 Z 16 #7 = Utf8 <init> 17 #8 = Utf8 ()V 18 #9 = Utf8 Code 19 #10 = Utf8 LineNumberTable 20 #11 = Utf8 LocalVariableTable 21 #12 = Utf8 this 22 #13 = Utf8 Lcom/example/springcloud/provider/demo/Demo; 23 #14 = Utf8 test 24 #15 = Utf8 SourceFile 25 #16 = Utf8 Demo.java 26 #17 = NameAndType #7:#8 // "<init>":()V 27 #18 = NameAndType #5:#6 // isOk:Z 28 #19 = Utf8 com/example/springcloud/provider/demo/Demo 29 #20 = Utf8 java/lang/Object 30 { 31 public com.example.springcloud.provider.demo.Demo(); 32 descriptor: ()V 33 flags: ACC_PUBLIC 34 Code: 35 stack=2, locals=1, args_size=1 36 0: aload_0 37 1: invokespecial #1 // Method java/lang/Object."<init>":()V 38 4: aload_0 39 5: iconst_1 40 6: putfield #2 // Field isOk:Z 41 9: return 42 LineNumberTable: 43 line 3: 0 44 line 4: 4 45 LocalVariableTable: 46 Start Length Slot Name Signature 47 0 10 0 this Lcom/example/springcloud/provider/demo/Demo; 48 49 public synchronized void test(); 50 descriptor: ()V 51 flags: ACC_PUBLIC, ACC_SYNCHRONIZED 52 Code: 53 stack=2, locals=1, args_size=1 54 0: aload_0 55 1: iconst_0 56 2: putfield #2 // Field isOk:Z 57 5: return 58 LineNumberTable: 59 line 7: 0 60 line 8: 5 61 LocalVariableTable: 62 Start Length Slot Name Signature 63 0 6 0 this Lcom/example/springcloud/provider/demo/Demo; 64 } 65 SourceFile: "Demo.java"
改为synchronized代码块:
1 package com.example.springcloud.provider.demo; 2 3 public class Demo { 4 private boolean isOk = true; 5 6 public void test() { 7 synchronized (this) { 8 isOk = false; 9 } 10 } 11 }
反编译汇编为:
1 Classfile /Users/shiwen/IdeaProjects/springcloud/example-springcloud-provider/target/classes/com/example/springcloud/provider/demo/Demo.class 2 Last modified 2017-10-11; size 536 bytes 3 MD5 checksum 64305bd51f24f439444d9240efd483fd 4 Compiled from "Demo.java" 5 public class com.example.springcloud.provider.demo.Demo 6 minor version: 0 7 major version: 52 8 flags: ACC_PUBLIC, ACC_SUPER 9 Constant pool: 10 #1 = Methodref #4.#21 // java/lang/Object."<init>":()V 11 #2 = Fieldref #3.#22 // com/example/springcloud/provider/demo/Demo.isOk:Z 12 #3 = Class #23 // com/example/springcloud/provider/demo/Demo 13 #4 = Class #24 // java/lang/Object 14 #5 = Utf8 isOk 15 #6 = Utf8 Z 16 #7 = Utf8 <init> 17 #8 = Utf8 ()V 18 #9 = Utf8 Code 19 #10 = Utf8 LineNumberTable 20 #11 = Utf8 LocalVariableTable 21 #12 = Utf8 this 22 #13 = Utf8 Lcom/example/springcloud/provider/demo/Demo; 23 #14 = Utf8 test 24 #15 = Utf8 StackMapTable 25 #16 = Class #23 // com/example/springcloud/provider/demo/Demo 26 #17 = Class #24 // java/lang/Object 27 #18 = Class #25 // java/lang/Throwable 28 #19 = Utf8 SourceFile 29 #20 = Utf8 Demo.java 30 #21 = NameAndType #7:#8 // "<init>":()V 31 #22 = NameAndType #5:#6 // isOk:Z 32 #23 = Utf8 com/example/springcloud/provider/demo/Demo 33 #24 = Utf8 java/lang/Object 34 #25 = Utf8 java/lang/Throwable 35 { 36 public com.example.springcloud.provider.demo.Demo(); 37 descriptor: ()V 38 flags: ACC_PUBLIC 39 Code: 40 stack=2, locals=1, args_size=1 41 0: aload_0 42 1: invokespecial #1 // Method java/lang/Object."<init>":()V 43 4: aload_0 44 5: iconst_1 45 6: putfield #2 // Field isOk:Z 46 9: return 47 LineNumberTable: 48 line 3: 0 49 line 4: 4 50 LocalVariableTable: 51 Start Length Slot Name Signature 52 0 10 0 this Lcom/example/springcloud/provider/demo/Demo; 53 54 public void test(); 55 descriptor: ()V 56 flags: ACC_PUBLIC 57 Code: 58 stack=2, locals=3, args_size=1 59 0: aload_0 60 1: dup 61 2: astore_1 62 3: monitorenter 63 4: aload_0 64 5: iconst_0 65 6: putfield #2 // Field isOk:Z 66 9: aload_1 67 10: monitorexit 68 11: goto 19 69 14: astore_2 70 15: aload_1 71 16: monitorexit 72 17: aload_2 73 18: athrow 74 19: return 75 Exception table: 76 from to target type 77 4 11 14 any 78 14 17 14 any 79 LineNumberTable: 80 line 7: 0 81 line 8: 4 82 line 9: 9 83 line 10: 19 84 LocalVariableTable: 85 Start Length Slot Name Signature 86 0 20 0 this Lcom/example/springcloud/provider/demo/Demo; 87 StackMapTable: number_of_entries = 2 88 frame_type = 255 /* full_frame */ 89 offset_delta = 14 90 locals = [ class com/example/springcloud/provider/demo/Demo, class java/lang/Object ] 91 stack = [ class java/lang/Throwable ] 92 frame_type = 250 /* chop */ 93 offset_delta = 4 94 } 95 SourceFile: "Demo.java"
和synchronized方法对比如下:
给isOk增加volatile关键字后
1 Classfile /Users/shiwen/IdeaProjects/springcloud/example-springcloud-provider/target/classes/com/example/springcloud/provider/demo/Demo.class 2 Last modified 2017-10-11; size 536 bytes 3 MD5 checksum 8dc910b015c7d5af2feac29d19f519a1 4 Compiled from "Demo.java" 5 public class com.example.springcloud.provider.demo.Demo 6 minor version: 0 7 major version: 52 8 flags: ACC_PUBLIC, ACC_SUPER 9 Constant pool: 10 #1 = Methodref #4.#21 // java/lang/Object."<init>":()V 11 #2 = Fieldref #3.#22 // com/example/springcloud/provider/demo/Demo.isOk:Z 12 #3 = Class #23 // com/example/springcloud/provider/demo/Demo 13 #4 = Class #24 // java/lang/Object 14 #5 = Utf8 isOk 15 #6 = Utf8 Z 16 #7 = Utf8 <init> 17 #8 = Utf8 ()V 18 #9 = Utf8 Code 19 #10 = Utf8 LineNumberTable 20 #11 = Utf8 LocalVariableTable 21 #12 = Utf8 this 22 #13 = Utf8 Lcom/example/springcloud/provider/demo/Demo; 23 #14 = Utf8 test 24 #15 = Utf8 StackMapTable 25 #16 = Class #23 // com/example/springcloud/provider/demo/Demo 26 #17 = Class #24 // java/lang/Object 27 #18 = Class #25 // java/lang/Throwable 28 #19 = Utf8 SourceFile 29 #20 = Utf8 Demo.java 30 #21 = NameAndType #7:#8 // "<init>":()V 31 #22 = NameAndType #5:#6 // isOk:Z 32 #23 = Utf8 com/example/springcloud/provider/demo/Demo 33 #24 = Utf8 java/lang/Object 34 #25 = Utf8 java/lang/Throwable 35 { 36 public volatile boolean isOk; 37 descriptor: Z 38 flags: ACC_PUBLIC, ACC_VOLATILE 39 40 public com.example.springcloud.provider.demo.Demo(); 41 descriptor: ()V 42 flags: ACC_PUBLIC 43 Code: 44 stack=2, locals=1, args_size=1 45 0: aload_0 46 1: invokespecial #1 // Method java/lang/Object."<init>":()V 47 4: aload_0 48 5: iconst_1 49 6: putfield #2 // Field isOk:Z 50 9: return 51 LineNumberTable: 52 line 3: 0 53 line 4: 4 54 LocalVariableTable: 55 Start Length Slot Name Signature 56 0 10 0 this Lcom/example/springcloud/provider/demo/Demo; 57 58 public void test(); 59 descriptor: ()V 60 flags: ACC_PUBLIC 61 Code: 62 stack=2, locals=3, args_size=1 63 0: aload_0 64 1: dup 65 2: astore_1 66 3: monitorenter 67 4: aload_0 68 5: iconst_0 69 6: putfield #2 // Field isOk:Z 70 9: aload_1 71 10: monitorexit 72 11: goto 19 73 14: astore_2 74 15: aload_1 75 16: monitorexit 76 17: aload_2 77 18: athrow 78 19: return 79 Exception table: 80 from to target type 81 4 11 14 any 82 14 17 14 any 83 LineNumberTable: 84 line 7: 0 85 line 8: 4 86 line 9: 9 87 line 10: 19 88 LocalVariableTable: 89 Start Length Slot Name Signature 90 0 20 0 this Lcom/example/springcloud/provider/demo/Demo; 91 StackMapTable: number_of_entries = 2 92 frame_type = 255 /* full_frame */ 93 offset_delta = 14 94 locals = [ class com/example/springcloud/provider/demo/Demo, class java/lang/Object ] 95 stack = [ class java/lang/Throwable ] 96 frame_type = 250 /* chop */ 97 offset_delta = 4 98 } 99 SourceFile: "Demo.java"
以上是关于java中synchronized关键字分析的主要内容,如果未能解决你的问题,请参考以下文章
Java并发编程专题系列之深入分析synchronized(基础篇)