![](http://static.blog.csdn.net/images/category_icon.jpg)
版权声明:本文为博主原创文章,未经博主允许不得转载。
同步代码块:
- package threads.ex1;
- class KitchenSync {
- private int[] intArray = new int[10];
- void reverseOrder() {
- synchronized (this) {
- int halfWay = intArray.length / 2;
- for (int i = 0; i < halfWay; ++i) {
- int upperIndex = intArray.length - 1 - i;
- int save = intArray[upperIndex];
- intArray[upperIndex] = intArray[i];
- intArray[i] = save;
- }
- }
- }
- }
反编译后的字节码:
- E:\Java\code\jvm\bin\threads\ex1>javap -verbose KitchenSync
- Compiled from "KitchenSync.java"
- class threads.ex1.KitchenSync extends java.lang.Object
- SourceFile: "KitchenSync.java"
- minor version: 0
- major version: 50
- Constant pool:
- const #1 = class #2; // threads/ex1/KitchenSync
- const #2 = Asciz threads/ex1/KitchenSync;
- const #3 = class #4; // java/lang/Object
- const #4 = Asciz java/lang/Object;
- const #5 = Asciz intArray;
- const #6 = Asciz [I;
- const #7 = Asciz <init>;
- const #8 = Asciz ()V;
- const #9 = Asciz Code;
- const #10 = Method #3.#11; // java/lang/Object."<init>":()V
- const #11 = NameAndType #7:#8;// "<init>":()V
- const #12 = Field #1.#13; // threads/ex1/KitchenSync.intArray:[I
- const #13 = NameAndType #5:#6;// intArray:[I
- const #14 = Asciz LineNumberTable;
- const #15 = Asciz LocalVariableTable;
- const #16 = Asciz this;
- const #17 = Asciz Lthreads/ex1/KitchenSync;;
- const #18 = Asciz reverseOrder;
- const #19 = Asciz halfWay;
- const #20 = Asciz I;
- const #21 = Asciz i;
- const #22 = Asciz upperIndex;
- const #23 = Asciz save;
- const #24 = Asciz StackMapTable;
- const #25 = class #26; // java/lang/Throwable
- const #26 = Asciz java/lang/Throwable;
- const #27 = Asciz SourceFile;
- const #28 = Asciz KitchenSync.java;
- {
- threads.ex1.KitchenSync();
- Code:
- Stack=2, Locals=1, Args_size=1
- 0: aload_0
- 1: invokespecial #10; //Method java/lang/Object."<init>":()V
- 4: aload_0
- 5: bipush 10
- 7: newarray int
- 9: putfield #12; //Field intArray:[I
- 12: return
- LineNumberTable:
- line 3: 0
- line 4: 4
- line 3: 12
- LocalVariableTable:
- Start Length Slot Name Signature
- 0 13 0 this Lthreads/ex1/KitchenSync;
- void reverseOrder();
- Code:
- Stack=4, Locals=6, Args_size=1
- 0: aload_0
- 1: dup
- 2: astore_1
- 3: monitorenter
- 4: aload_0
- 5: getfield #12; //Field intArray:[I
- 8: arraylength
- 9: iconst_2
- 10: idiv
- 11: istore_2
- 12: iconst_0
- 13: istore_3
- 14: goto 61
- 17: aload_0
- 18: getfield #12; //Field intArray:[I
- 21: arraylength
- 22: iconst_1
- 23: isub
- 24: iload_3
- 25: isub
- 26: istore 4
- 28: aload_0
- 29: getfield #12; //Field intArray:[I
- 32: iload 4
- 34: iaload
- 35: istore 5
- 37: aload_0
- 38: getfield #12; //Field intArray:[I
- 41: iload 4
- 43: aload_0
- 44: getfield #12; //Field intArray:[I
- 47: iload_3
- 48: iaload
- 49: iastore
- 50: aload_0
- 51: getfield #12; //Field intArray:[I
- 54: iload_3
- 55: iload 5
- 57: iastore
- 58: iinc 3, 1
- 61: iload_3
- 62: iload_2
- 63: if_icmplt 17
- 66: aload_1
- 67: monitorexit
- 68: goto 74
- 71: aload_1
- 72: monitorexit
- 73: athrow
- 74: return
- Exception table:
- from to target type
- 4 68 71 any
- 71 73 71 any
- LineNumberTable:
- line 7: 0
- line 8: 4
- line 9: 12
- line 10: 17
- line 11: 28
- line 12: 37
- line 13: 50
- line 9: 58
- line 7: 66
- line 16: 74
- LocalVariableTable:
- Start Length Slot Name Signature
- 0 75 0 this Lthreads/ex1/KitchenSync;
- 12 54 2 halfWay I
- 14 52 3 i I
- 28 30 4 upperIndex I
- 37 21 5 save I
- StackMapTable: number_of_entries = 4
- frame_type = 254 /* append */
- offset_delta = 17
- locals = [ class threads/ex1/KitchenSync, int, int ]
- frame_type = 43 /* same */
- frame_type = 255 /* full_frame */
- offset_delta = 9
- locals = [ class threads/ex1/KitchenSync, class threads/ex1/KitchenSync ]
- stack = [ class java/lang/Throwable ]
- frame_type = 250 /* chop */
- offset_delta = 2
- }
分析
方法内的同步语句会使用两个指令:
monitorenter | c2 | objectref → | enter monitor for object ("grab the lock" - start of synchronized() section) | |
monitorexit | c3 | objectref → | exit monitor for object ("release the lock" - end of synchronized() section) |
当java虚拟机遇到monitorenter的时候,它获得栈中objectref所引用的对象的锁。如果线程已经拥有了那个对象的锁,锁的计数器会加1。线程中每条monitorexit指令都会引起计数器减1。当计数器变成0的时候,监视器就释放了。
而且return后,还有Exception table。
同步方法:
- package threads.ex1;
- class HeatSync {
- private int[] intArray = new int[10];
- synchronized void reverseOrder() {
- int halfWay = intArray.length / 2;
- for (int i = 0; i < halfWay; ++i) {
- int upperIndex = intArray.length - 1 - i;
- int save = intArray[upperIndex];
- intArray[upperIndex] = intArray[i];
- intArray[i] = save;
- }
- }
- }
反编译后的字节码:
- E:\Java\code\jvm\bin\threads\ex1>javap -verbose HeatSync
- Compiled from "HeatSync.java"
- class threads.ex1.HeatSync extends java.lang.Object
- SourceFile: "HeatSync.java"
- minor version: 0
- major version: 50
- Constant pool:
- const #1 = class #2; // threads/ex1/HeatSync
- const #2 = Asciz threads/ex1/HeatSync;
- const #3 = class #4; // java/lang/Object
- const #4 = Asciz java/lang/Object;
- const #5 = Asciz intArray;
- const #6 = Asciz [I;
- const #7 = Asciz <init>;
- const #8 = Asciz ()V;
- const #9 = Asciz Code;
- const #10 = Method #3.#11; // java/lang/Object."<init>":()V
- const #11 = NameAndType #7:#8;// "<init>":()V
- const #12 = Field #1.#13; // threads/ex1/HeatSync.intArray:[I
- const #13 = NameAndType #5:#6;// intArray:[I
- const #14 = Asciz LineNumberTable;
- const #15 = Asciz LocalVariableTable;
- const #16 = Asciz this;
- const #17 = Asciz Lthreads/ex1/HeatSync;;
- const #18 = Asciz reverseOrder;
- const #19 = Asciz halfWay;
- const #20 = Asciz I;
- const #21 = Asciz i;
- const #22 = Asciz upperIndex;
- const #23 = Asciz save;
- const #24 = Asciz StackMapTable;
- const #25 = Asciz SourceFile;
- const #26 = Asciz HeatSync.java;
- {
- threads.ex1.HeatSync();
- Code:
- Stack=2, Locals=1, Args_size=1
- 0: aload_0
- 1: invokespecial #10; //Method java/lang/Object."<init>":()V
- 4: aload_0
- 5: bipush 10
- 7: newarray int
- 9: putfield #12; //Field intArray:[I
- 12: return
- LineNumberTable:
- line 3: 0
- line 4: 4
- line 3: 12
- LocalVariableTable:
- Start Length Slot Name Signature
- 0 13 0 this Lthreads/ex1/HeatSync;
- synchronized void reverseOrder();
- Code:
- Stack=4, Locals=5, Args_size=1
- 0: aload_0
- 1: getfield #12; //Field intArray:[I
- 4: arraylength
- 5: iconst_2
- 6: idiv
- 7: istore_1
- 8: iconst_0
- 9: istore_2
- 10: goto 54
- 13: aload_0
- 14: getfield #12; //Field intArray:[I
- 17: arraylength
- 18: iconst_1
- 19: isub
- 20: iload_2
- 21: isub
- 22: istore_3
- 23: aload_0
- 24: getfield #12; //Field intArray:[I
- 27: iload_3
- 28: iaload
- 29: istore 4
- 31: aload_0
- 32: getfield #12; //Field intArray:[I
- 35: iload_3
- 36: aload_0
- 37: getfield #12; //Field intArray:[I
- 40: iload_2
- 41: iaload
- 42: iastore
- 43: aload_0
- 44: getfield #12; //Field intArray:[I
- 47: iload_2
- 48: iload 4
- 50: iastore
- 51: iinc 2, 1
- 54: iload_2
- 55: iload_1
- 56: if_icmplt 13
- 59: return
- LineNumberTable:
- line 7: 0
- line 8: 8
- line 9: 13
- line 10: 23
- line 11: 31
- line 12: 43
- line 8: 51
- line 14: 59
- LocalVariableTable:
- Start Length Slot Name Signature
- 0 60 0 this Lthreads/ex1/HeatSync;
- 8 52 1 halfWay I
- 10 49 2 i I
- 23 28 3 upperIndex I
- 31 20 4 save I
- StackMapTable: number_of_entries = 2
- frame_type = 253 /* append */
- offset_delta = 13
- locals = [ int, int ]
- frame_type = 40 /* same */
- }
分析
可以看到,同步方法没有使用monitorenter和monitorexit这两个指令。
方法return后也没有Exception table。
当虚拟机解析对方法的符号引用时,它判断这个方法是否是同步的。如果是同步的,虚拟机就在调用方法之前获取一个锁。
总结
因此,同步方法比同步代码块更高效,但是它们的功能是一样的。
-
顶
- 0
-
踩
- 0