java同步方法和同步代码块的区别
2016-01-24 19:07
686 查看
java同步方法和同步代码块的区别
2014-03-25 21:13 3068人阅读 评论(0) 收藏 举报分类:
java(120)
版权声明:本文为博主原创文章,未经博主允许不得转载。
目录(?)[+]
同步代码块:
[java] viewplaincopy
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;
}
}
}
}
反编译后的字节码:
[plain] viewplaincopy
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) |
而且return后,还有Exception table。
同步方法:
[java] viewplaincopy
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;
}
}
}
反编译后的字节码:
[plain] viewplaincopy
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。
当虚拟机解析对方法的符号引用时,它判断这个方法是否是同步的。如果是同步的,虚拟机就在调用方法之前获取一个锁。
总结
因此,同步方法比同步代码块更高效,但是它们的功能是一样的。相关文章推荐
- java笔记--关于线程同步(5种同步方式)
- java 同步锁(synchronized)
- poi合并单元格
- Java字符转C的思路
- Java 异常的注意事项
- Java字符转C的思路
- JavaHello_记事本程序
- win8.1_javaSE8安装配置
- 关于java的方法同步
- JDK和Cglib动态代理小demo
- 数据挖掘学习笔记-决策树算法浅析(含Java实现)
- Java byte数组转有符号int
- hdu1850 Being a Good Boy in Spring Festival
- spring 配置文件中的占位符 使用 context:property-placeholder
- 简单的java爬虫实现
- Java实现Windows系统服务 JavaService
- C 与 JAVA 的对比分析
- 深入理解Java:注解(Annotation)自定义注解入门
- 使用struts2+spring+hibernate测试多对多关系映射的时候出现懒加载问题:could not initialize proxy - no Session
- JavaEE Tutorials (30) - Duke综合案例研究示例