一 sysnchronized的作用
- 保证代码互斥的访问临界区(每次只允许一个线程访问的区域)
- 保证共享资源的修改能够及时可见
二 用法
- 修饰代码块
- 修饰普通方法
- 修饰静态方法
三 个人理解
同步块就相当于在方法内限定了一个小范围的--局部临界区,synchronized的对象就相当于学操作系统进程同步信号量机制的那个信号量,只不过这个信号量为1,因为jvm限定了只能有一个线程拿到(修改)这个"信号量"。
而同步方法、同步静态方法就相当于整个方法作用域都作为临界区。
javap反编译可以看到进入同步块前后由两个指令,monitorenter和monitorexit.
Compiled from "Human.java"
public class com.backgulf.tyrell.Human {
public com.backgulf.tyrell.Human();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_0
6: putfield #2 // Field age:I
9: return
public void method1();
Code:
0: iconst_0
1: istore_1
2: iload_1
3: sipush 1000
6: if_icmpge 67
9: aload_0
10: dup
11: astore_2
12: monitorenter
13: aload_0
14: dup
15: getfield #2 // Field age:I
18: iconst_1
19: iadd
20: putfield #2 // Field age:I
23: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
26: new #4 // class java/lang/StringBuilder
29: dup
30: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V
33: ldc #6 // String 生产一张还有:
35: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
38: aload_0
39: getfield #2 // Field age:I
42: invokevirtual #8 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
45: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
48: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
51: aload_2
52: monitorexit
53: goto 61
56: astore_3
57: aload_2
58: monitorexit
59: aload_3
60: athrow
61: iinc 1, 1
64: goto 2
67: return
Exception table:
from to target type
13 53 56 any
56 59 56 any
但是对于同步方法来说常量池中多了ACC_SYNCHRONIZED标示符,所以使用synchronized时应注意这个"信号量"锁是不是加在同一个上。
## 今天也是想你的一天 ^_^~