avatar

synchronized同步锁原理

介绍

  • 在多线程操作中volatile关键字可以保证共享变量的内存可见性, 但是并不能保证操作的原子性, 这时候就需要用到锁, synchronized同步锁是java关键字, 是内置的语言实现.
  • synchronized加锁和线程结束或异常锁的释放过程由JVM进行控制
  • synchronized关键字可以使用在方法和同步代码块中, 不同的使用方式, 锁的结果是不同的
  • 重量级锁 + 可重入

synchronized底层原理

1.代码示例

package com.liuzhihang.tool.java;

/**
* @author liuzhihang
* @date 2018/06/11 16:05
*/
public class SynchronizedTest {

private int i;

private int j;

public void syncTest1() {

synchronized (this) {
i++;
}
}

public synchronized void syncTest2() {

j++;
}


}

2.使用 javap -v SynchronizedTest.class 查看代码的对应字节码如下:

$ javap -v SynchronizedTest.class
Classfile /C:/Users/liuzhihang/Desktop/SynchronizedTest.class
Last modified 2018-7-10; size 518 bytes
MD5 checksum ba48def77b226e7b9ac28121ec423c16
Compiled from "SynchronizedTest.java"
public class com.liuzhihang.tool.java.SynchronizedTest
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
// 常量池省略
{
// 构造方法省略

public void syncTest1();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=3, locals=3, args_size=1
0: aload_0
1: dup
2: astore_1
3: monitorenter
4: aload_0
5: dup
6: getfield #2 // Field i:I
9: iconst_1
10: iadd
11: putfield #2 // Field i:I
14: aload_1
15: monitorexit
16: goto 24
19: astore_2
20: aload_1
21: monitorexit
22: aload_2
23: athrow
24: return
Exception table:
// 省略代码

public synchronized void syncTest2();
descriptor: ()V
flags: ACC_PUBLIC, ACC_SYNCHRONIZED
Code:
stack=3, locals=1, args_size=1
0: aload_0
1: dup
2: getfield #3 // Field j:I
5: iconst_1
6: iadd
7: putfield #3 // Field j:I
10: return
LineNumberTable:
line 22: 0
line 23: 10
}
SourceFile: "SynchronizedTest.java"

3.结论

  • 同步语句块的实现使用的是 monitorenter 和 monitorexit 指令, 其中有两个 monitorexit 因为不能确保是正常结束还是异常结束, 所以另一个是用来确保异常结束时释放 monitor指令.
  • 同步方法时使用的是 flags中的 ACC_SYNCHRONIZED 来标识该方法为同步方法, JVM在调用该方法时便会执行相应的同步调用.
  • 每个线程都维护自己的监视器(monitor), 只要是同步调用进行相关操作时要先获得 monitor, 否则将被阻塞
文章作者: liuzhihang
文章链接: https://liuzhihang.com/2018/06/11/synchronized-synchronous-lock-principle.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Notes

评论