文章目录
- ⭐synchronized(内置锁)
- 1. synchronized 的基本使用
- 1.1 修饰静态方法
- 1.2 修饰普通方法
- 1.3 修饰代码块
- 2. synchronized 的特性
- 2.1 互斥性(原子性)
- 2.2 刷新内存(可见性)
- 2.3 可重入(有序性)
- 3. synchronized 的底层实现原理
使用锁是 Java 中解决线程安全问题中最主要的手段。
⭐synchronized(内置锁)
synchronized 是 Java 中的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码,而这段代码也被称为临界区。
1. synchronized 的基本使用
synchronized 的基本用法有以下三种:
- 修饰静态方法
- 修饰普通方法
- 修饰代码块
1.1 修饰静态方法
synchronized 修饰的方法是静态方法时,则是类锁。
public synchronized static int countData(int data){
return data*data;
}
- 1
- 2
- 3
1.2 修饰普通方法
synchronized 修饰的方法是普通成员方法时,则是对象锁,就是是以当前对象为锁,即调用这个方法的对象。
public synchronized void incr() {
for(int i = 0; i < MAX_COUNT; i++) {
number++;
}
}
- 1
- 2
- 3
- 4
- 5
1.3 修饰代码块
修饰代码块时,加锁的对象有三种:
public void decr() {
synchronized (object) {
}
}
- 1
- 2
- 3
- 4
是 this 时,是对象锁,可以在非静态方法中使用,不能在静态方法中使用。
public static void test(){
synchronized (this) {
}
}
- 1
- 2
- 3
- 4
是类名.class 时,是一个类的 class 对象,就是类锁。可以在静态、非静态方法中使用。
public void test() {
synchronized (类名.class) {
}
}
- 1
- 2
- 3
- 4
3.自定义锁对象, object 是一个对象实例。
如果是静态对象,就是类锁;如果是非静态对象,就是对象锁。
public void test() {
Count count = null;
synchronized (count) {
}
}
- 1
- 2
- 3
- 4
- 5
注意事项:加锁时一定要注意对于同一个业务的多个线程加锁对象,一定要是同一个对象。
2. synchronized 的特性
2.1 互斥性(原子性)
synchronized 会起到互斥效果,某个线程执行到某个对象的 synchronized 中时,其他线程如果也执行到同一个对象的 synchronized 就会阻塞等待。起到了原子性的作用,确保线程互斥的访问同步代码。
2.2 刷新内存(可见性)
synchronized 工作时,先获得互斥锁,再从主内存拷贝变量的最新副本到工作内存中,执行代码,将更改后的共享变量的值刷新到主内存中,然后释放互斥锁。这样就保证了内存可见性。
2.3 可重入(有序性)
synchronized 同步块对同一条线程来说是可重入的,有效的解决了重排序问题,即一个变量在同一时刻只允许一条线程对其进行 lock 操作,实现了有序性。
3. synchronized 的底层实现原理
在 JVM 层面,synchronized 同步锁是依靠监视器 monitor 实现的。
synchronized 同步代码块的实现是通过 monitorenter 和 monitorexit 指令,其中 monitorenter 指令指向同步代码块的开始位置,monitorexit 指令则指明同步代码块的结束位置。当 jvm执行到 monitorenter 指令时,当前线程试图获取monitor 对象的所有权,如果未加锁或者已经被当前线程所持有,就把锁的计数器+1;当执行 monitorexit 指令时,锁计数器-1;当锁计数器为0时,该锁就被释放了。如果获取 monitor 对象失败,该线程则会进入阻塞状态,直到其他线程释放锁。
synchronized 修饰的方法是隐式的,无需通过字节码指令来控制,所以没有 monitorenter 指令和 monitorexit 指令,取而代之的 ACC_SYNCHRONIZED 标识,该标识指明了该方法是一个同步方法,JVM 通过该 ACC_SYNCHRONIZED 访问标志来辨别一个方法是否声明为同步方法,从而执行相应的同步调用。
活动地址:****21天学习挑战赛