java面试:可以讲一讲sychronized和ReentrantLock的异同点吗

在java面试当中sychronized与ReentrantLock都是用来实现Java当中的排他锁和互斥锁的,二者虽然有及其相同的用法,但是在许多的细节方面却有许多不同,今天我们就将这两个锁做一个细分,希望大家能有所收获。

1.Sychronized和ReentrantLock的相同点

二者都具有互斥性,不论是sychronized锁还是ReentrantLock锁,两者都是独占锁(排他锁),同一时间只允许一个线程访问被保护的代码块或资源,都是实现互斥锁的方案。

**二者都具有可重入性,**两者都是可重入锁,当java中某个递归函数使得一个线程多次获取锁时,同一个线程通过锁自动生成的锁计数器可以保证可以多次获取同一把锁而不会造成死锁。

二者都具有可见性, 两者都遵循 Happens-Before原则,能够保证在释放锁之后,对共享变量的修改对后续获取该锁的线程是可见的。

2.Sychronized和ReentrantLock的不同点

1.实现级别​: sychronized是java提供的一个关键字,是JVM层面的锁,而reentrantlock是JDK提供的一个类,是API层面的锁。

2.锁的获取与释放 **​:**sychronized能够通过编译器来自动加锁,当代码块出现异常时又能通过JVM来自动释放锁,而reentrantlock需要通过Lock()和unLock()方法来手动添加锁和释放锁。

**3.灵活性​:**sychronized锁的获取和释放固守在单个代码块的结构中,是不能获取当前线程是否上锁的,而reentrantlock可以在一个方法中获取锁,在另一个方法中释放锁,可以尝试非阻塞地获取锁、尝试超时获取锁等。

4.公平锁选项​: sychronized不支持公平锁​​,它​ 不保证 ​等待时间最长的线程会优先获得锁(是非公平的),reentrantlock支持公平锁 ​,构造函数中可以传入 true来创建一个公平锁(保证先来先服务),但会有性能代价,默认是非公平的。

5.等待可中断​: sychronized不可中断​​,如果线程在等待获取 synchronized锁,它是不可被中断的,reentrantlock可中断 ​,提供了 lockInterruptibly()方法,允许在等待锁的过程中响应中断。

**6.锁信息的存储:**sychronized锁的是对象,将锁的信息保存在对象头当中的,而reentrantlock是通过int类型的state来标识锁的状态的。

**7.锁升级的过程:**sychronized锁可以进行锁升级,而reentrantlock并不具有。

3.如何选择两个锁

优先使用 synchronized, 绝大多数情况​​下,应优先考虑 synchronized,因为它更简单、更安全、代码更简洁,并且随着 JVM 的优化,其性能已经非常出色。

synchronized的简单用法:

java 复制代码
public class SynchronizedExample {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }
}
  • 当你需要 ​ReentrantLock提供的高级功能时​​:

    • ​​可中断的锁获取​​。

    • 超时获取锁​​,避免死等。

    • 公平锁​​需求(但性能会有所下降)。

否则不需要引入复杂的reentrantlock。

reentrantlock的简单用法:

java 复制代码
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockExample {
    private int count = 0;
    private final ReentrantLock lock = new ReentrantLock();

    public void increment() {
        lock.lock(); // 手动上锁
        try {
            count++;
        } finally {
            lock.unlock(); // 必须在 finally 中手动释放锁
        }
    }
}

今天的分享就到这里了,希望这篇博客能给你一些帮助,让你对关于sychronized和ReentrantLock的异同点的问题得到进一步的提升,在面试的时候能从容面对面试官。

相关推荐
東隅已逝,桑榆非晚11 小时前
新手入门指南:认识 C 语言文件操作(上)
c语言·开发语言·笔记
cany100011 小时前
C++ -- 动态内存分配和释放(new/delete)
开发语言·c++
MaCa .BaKa11 小时前
55-宠物爱心救助领养系统-宠物救助领养系统
java·vue.js·tomcat·maven·springboot·宠物救助领养系统
brycegao32111 小时前
Vue3+Go 全栈项目上线阿里云|从 0 到 1 踩坑全纪录
开发语言·阿里云·golang
ch.ju11 小时前
Java Programming Chapter 4——cite
java·开发语言
小张小张爱学习11 小时前
Spring Boot 多线程并发入门教程:ThreadPoolTaskExecutor + CompletableFuture
java·spring boot·后端
西安邮电大学11 小时前
Redis核心数据结构以及应用场景
java·redis·后端·其他·面试
优雅格子衫11 小时前
uniapp 拍照相册选取后超级好用的裁剪组件,增加水印完全自定义
开发语言·前端·javascript·uni-app·vue
NiceCloud喜云11 小时前
Claude Code 跑 HyperFrames 实测:本地生成 AI 视频素材全流程
java·运维·人工智能·自动化·json·音视频·飞书
lili001211 小时前
Claude自动修Bug配置优化与避坑指南
java·人工智能·python·bug·ai编程