Synchronized 关键字

本文详细解析了Java中Synchronized关键字的使用方法,包括对象锁、类锁的不同形式及多线程环境下锁的竞争与互斥特性。探讨了Synchronized的可重入性、不可中断性及内存可见性,同时指出了其效率与灵活性的局限。

Synchronized 关键字

synchronized 同步方法支持一种简单的策略来防止线程干扰和内存一致性错误:即如果一个对象对多个线程可见,则该对象变量的所有读写操作都是通过同步方法完成。

synchronized 修饰的代码段,能够保证在同一时刻最多只有一个线程执行,以达到保证并发安全的效果。

用法

1 对象锁

1.1 代码块形式

手动指定锁对象

static final Object LOCK_1 = new Object();

synchronized (LOCK_1) {
    // do method
}
1.2 方法锁形式

synchronized 修饰方法,默认锁对象为this

private synchronized void doMethod() {
    // do method
}

2 类锁

Java 类可能会有很多个对象,但只有1个 Class 对象。类锁,相当于 Class 对象的锁。即类锁只能在同一时刻被一个对象拥有。

2.1 静态方法锁
private static synchronized void doMethod() {
    // do method
}
2.1 synchronized(*.class) 代码块

synchronized 修饰静态的方法或指定锁为 Class 对象

public class SyncClassClass {

    private void doMethod() {
        synchronized (SyncClassClass.class) {
            // do method
        }
    }
}

多线程访问同步方法的面试点

1 多线程同时访问一个对象的synchronized方法

多线程会发生对同步方法锁的竞争,当一个线程竞争到锁时,其余线程会阻塞等待。

2 多线程访问的是两个对象的synchronized方法

因为对象锁的方法锁,默认为this当前实例对象,因此每一个线程的锁相互独立,并不互斥,会发生并发问题。

3 多线程同时访问一个对象的静态synchronized方法

多线程会发生对同步方法锁的竞争,当一个线程竞争到锁时,其余线程会阻塞等待。

4 多线程同时访问一个对象的synchronized方法与非同步方法

synchronized 只作用于同步方法,非同步方法不受影响,因此同步方法与非同步方法可以并行。

5 多线程同时访问一个对象的不同的synchronized方法

因为对象锁的方法锁,默认为this当前实例对象,因此对于同一个实例对象,同步锁会发生互斥,不同的同步方法将会串行执行。

6 多线程同时访问一个对象的静态synchronized与非静态synchronized方法

静态synchronized锁为类锁,非静态synchronized锁为对象锁,类锁与对象锁之间不会发生互斥,因此静态synchronized方法和非静态synchronized方法将会同时执行。

7 synchronized方法抛异常后,会释放锁

  • synchronized :抛异常后会自动释放锁。
  • Lock :抛异常不会主动释放锁。

性质

1 可重入

指同一线程的外层函数获得锁之后,内层函数可以直接再次获取该锁。

好处:避免死锁,提升封装性。

粒度:线程非调用。

原理:利用加锁次数计数器。即线程第一次给对象加锁的时候,计数变为1,每当这个相同的线程在此对象上再次获得锁时,计数会递增;每当任务离开时,计数会递减,当计数为0时,锁被完全释放。

2 不可中断

当一个锁被某一线程持有时,其余线程只能阻塞等待该线程释放锁。如果该线程不释放锁,则其余线程只能永远等待。

内存可见性

内存可见性

缺点

  • 效率低:锁的释放情况少、试图获得锁时不能设定超时、不能中断一个正在试图获得锁的线程。
  • 不够灵活:加锁和释放的时机单一,每个锁仅有单一的条件。
  • 无法知道是否成功获取到锁

参考

  1. Java高并发之魂:synchronized深度解析
  2. GitHub
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值