首页 > 其他分享 >synchronized 和 ReentrantLock (Lock)区别,优劣对比

synchronized 和 ReentrantLock (Lock)区别,优劣对比

时间:2024-06-21 14:10:21浏览次数:23  
标签:synchronized 获取 Lock ReentrantLock 接口 并发 session

两种方法都是为了确保多线程环境中的线程安全,但它们使用了不同的同步机制:synchronized 关键字和 Lock 接口。下面详细对比这两种方法的区别、优缺点以及适用场景。

synchronized 关键字

public synchronized void addSession(HttpSession session) {
    if (session != null) {
        sessionMap.put(session.getId(), session);
    }
}

优点

  1. 简单易用:synchronized 关键字内置于 Java 语言中,使用方便,容易理解。
  2. 隐式锁:锁的获取和释放由 JVM 自动管理,不需要显式的解锁操作,减少了编程错误的可能性。
  3. 异常处理:锁的释放是自动的,即使抛出异常也会自动释放锁,避免了死锁的风险。

缺点

  1. 灵活性低:无法中断正在等待的线程,除非超时(使用 wait 和 notify 机制)。
  2. 性能问题:在高并发情况下,synchronized 的性能可能不如 Lock 接口,因为 synchronized 只能是阻塞的,无法实现更高级的并发控制。
  3. 不可尝试获取锁:不能尝试获取锁,并在获取不到时执行其他逻辑。

Lock 接口

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Example {
    private final Lock lock = new ReentrantLock();

    public void addPlayer(Integer userId, Integer rating, Integer selected_bot_id) {
        lock.lock();
        try {
            players.add(new Player(userId, rating, selected_bot_id, 0));
        } finally {
            lock.unlock();
        }
    }
}

优点

  1. 灵活性高:提供了多种锁获取模式(可中断、不可中断、限时等待等),适用于更复杂的并发控制。
  2. 性能好:在高并发环境中,Lock 接口的性能可能优于 synchronized,特别是在需要频繁锁定和解锁的情况下。
  3. 可尝试获取锁:可以尝试获取锁,并在获取不到时执行其他逻辑,避免长时间等待。

缺点

  1. 复杂性高:需要显式地获取和释放锁,容易出现忘记解锁的编程错误,从而导致死锁。
  2. 异常处理复杂:需要在 finally 块中显式释放锁,增加了代码的复杂性。

对比总结

image

使用场景

synchronized
适用于简单的同步需求,代码块较短,锁竞争不激烈的情况。
适合初学者,简单易用,降低编程错误。
Lock 接口:
适用于复杂的并发控制需求,代码块较长,锁竞争激烈的情况。
需要更高的性能和灵活性,能处理更多并发场景(如可中断锁、限时锁等)。

结论

选择 synchronized:如果你的同步需求较简单,代码块较短且锁竞争不激烈,使用 synchronized 更加方便且安全。

选择 Lock 接口:如果你的同步需求较复杂,代码块较长且锁竞争激烈,使用 Lock 接口可以提供更高的性能和灵活性。

标签:synchronized,获取,Lock,ReentrantLock,接口,并发,session
From: https://www.cnblogs.com/rdisheng/p/18260384

相关文章

  • java synchronized 保护线程安全
    前言工作中自己实现了一个MySessionContext类,在实现addSession方法的时候,考虑到会有线程不安全问题,这里需要使用synchronized关键字来保护线程安全。理解synchronized关键字需要了解多线程和线程安全的基本概念。在多线程环境中,多个线程可以同时访问共享资源(例如内存中的变量......
  • abstract 的 method 是否可同时是 static,是否可同时是 native,是否可同时是 synchroni
    在Java中,abstract方法不能同时是static、native或synchronized。让我们详细解释每种情况,并提供相应的代码示例和解释:abstract方法不能是static:abstract方法必须被子类实现,而static方法是与类相关的,而不是与实例相关的。因此,不能将一个方法同时声明为abstract和......
  • nalog_clock 时钟
    analog_clock:^0.1.0#时钟 classMyApp1extendsStatelessWidget{@overrideWidgetbuild(BuildContextcontext){//获取当前北京时间returnCenter(child:AnalogClock(//时钟的装饰,指定边框、背景色和形状decoration:BoxDecorat......
  • SQL 中为什么经常要加NOLOCK?
    刚开始工作的时候,经常听同事说在SQL代码的表后面加上WITH(NOLOCK)会好一些,后来仔细研究测试了一下,终于知道为什么了。那么加与不加到底有什么区别呢?SQL在每次新建一个查询,就相当于创建了一个会话。在不同的查询窗口操作,会影响到其他会话的查询。当某张表正在写数据时,这时候去查......
  • 罗技键盘 Caps Lock 键 bug 解决
    Mac上的CapsLock键对于多语言用户来说,除了切换输入大小写的作用外还承担着切换输入法的功能。正常情况下,轻按一下CapsLock键是切换输入法,长按是切换输入大小写。然而有时这个功能会失灵,轻按一下就直接切换输入大小写了。当我们经常在两种输入法之间切换时,这个失灵的问题很......
  • synchronized原理
    锁的四种状态001:无锁。101:偏向锁。00:轻量级锁。此状态下,线程可能通过自旋的方式竞争锁。10:重量级锁。线程阻塞被挂起,需要从用户态切换到内核态进行系统调用,获取CPU调度权,对性能有较大影响。轻量级锁,重量级锁是2Bit锁等级顺序:001无锁--》101偏向锁--》00轻......
  • 快速解决:使用Mindspore框架时报错!!libgomp-6e1a1d1b.so.1.0.0: cannot allocate memory
    前言:最近在用ms跑大模型,需要做好多步骤,遇到报错跟大家一起分析一下吧刚开始转换权重就遇到了下述报错:ImportError:/root/anaconda3/envs/MS/lib/python3.9/site-packages/torch/lib/../../torch.libs/libgomp-6e1a1d1b.so.1.0.0:cannotallocatememoryinstaticTLSblo......
  • BitLocker加密分区丢失了如何恢复?
    关于BitLocker加密分区丢失与恢复BitLocker是Windows操作系统提供的磁盘加密技术,可以更好的保护电脑中的数据。被BitLocker加密后的分区,在文件管理器中可以看到分区上会有个黄色的锁(如下图所示),双击该分区,会弹出窗口要求输入密码或是秘钥。输入正确的密码/秘钥后,即可解锁BitLocke......
  • VMware ESXi 8.0U2c macOS Unlocker & OEM BIOS ConnectX-3 网卡定制版 (集成驱动版)
    VMwareESXi8.0U2cmacOSUnlocker&OEMBIOSConnectX-3网卡定制版(集成驱动版)发布ESXi8.0U2集成驱动版,在个人电脑上运行企业级工作负载请访问原文链接:https://sysin.org/blog/vmware-esxi-8-u2-sysin/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org......
  • Linux PM:wakeup count、wakelock、autosleep
     在进行wakeupcount、wakelock、autosleep之前,先参考《Linux电源管理(7)_Wakeupeventsframework(wowotech.net)》。下面简单跟一下,wakeupcount、wakelock、autosleep,及其使用方法。1PM初始化PM子系统初始化:pm_initpm_start_workqueuehibernate_image_size_ini......