synchronized的功能的扩展:重入锁

简介: synchronized的功能的扩展:重入锁

重入锁

重入锁可以说是synchronized,Object.wait(),Object.notify()的一种替代品。

在JDK5的早期版本,重入锁的新能要比synchronized好很多,在JDK6后对synchronized进行可很多优化,使得他和重入锁的性能差距并不大。
AI 代码解读

重入锁使用java.util.concurrent.locks.ReentrantLock类实现,下面我么来看下重入锁的简单使用案例:

import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
public class ReenterLock implements Runnable {
    public static ReentrantLock lock=new ReentrantLock();
    public static int i=0;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int j=0;j<10000000;j++) {
            lock.lock();
            try {
                i++;
            }finally {
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub
        ReenterLock tl=new ReenterLock();
        Thread t1=new Thread(tl);
        Thread t2=new Thread(tl);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(i);
    }

}
AI 代码解读

运行程序可以得到结果为20000000.

重入锁具有很高的灵活性,需要开发人员手动用lock()与unlock()函数来指定何时加锁何时解锁,但是需要注意的是,在离开临界区的时候要记得释放锁,否则其他线程就没有机会在访问临界区了。(之所以叫重入锁是因为这种锁可以反复进入,但是记得一个线程同时获得多少锁,也必须释放相同的次数)

重入锁除了使用上的灵活性,还有一些高级的功能。

中断响应

对于synchronized来说,如果一个线程在等待锁,那么结果只有两种情况,要么获得锁继续执行,要么保持等待。但是使用重入锁。则提供了另外一种可能,就是线程可以被中断。也就是说,在等待锁的过程中,线程可以取消对锁的请求。有些时候这么做是很有必要的,比如和好朋友约好去打球,等了半小时没到,街道电话得知朋友临时有事,不能来了,那么就打道回府了。这种情况对于处理死锁有一定的帮助。使用lockInterruptibly()函数表示重入锁可以响应中断。

锁申请限时等待

除了等待外部通知外,要避免死锁还有一种办法,就是限时等待。我么可以通过tryLock方法进行一次限时的等待。

try{
    if(lock.tryLock(5,TimeUnit.SECONDS)){
        Thread.sleep(6000);
        }else{
            System.out.println("get lock failed");
        }
    }catch(InterruptdeException e){
        e.printStackTrace();
    }finally{
    if(lock.isHeldByCurrentThread()) lock.unlock();}
}
AI 代码解读

上面代码中,设置的5秒的限时等待,由于睡眠了6秒,或导致请求锁失败。
tryLock也可以不带参数进行运行,这种情况下,线程会尝试获得锁,如果锁未被其他线程占用,申请锁成功,返回true,否则申请失败,线程也不会进行等待,直接返回false。

公平锁

大多数情况下锁是不公平的,也就是说不一定先请求就先获得锁,使用synchronized关键字实现锁,锁就是不公平的,重入锁可以实现公平锁,避免现象,也就是说,只要你排队,就能获得锁,但是由于需要维护一个有序队列,导致公平锁的实现成本比较高,性能相对也非常低下。重入锁有如下一个构造函数:
public ReentrantLock(boolean fair)
当参数为true时锁是公平的的。

重入锁的好搭档:Condition条件

Condition与Object.wait(),Object.notify()方法的作用大致相同,只不过是用来与重入锁相关联的。通过Lock接口(出入锁就实现乐这一接口)的Condition newCondition()方法可以生成与当前重入锁对象绑定的Condition实例,利用Condition对象,我们可以让线程在特定的时刻进行等待,或者在某一个特定的时刻得到通知,继续执行。
Condition接口提供的方法如下。

void await() throws InterrupttedExceptionI;
void awaitUninterruptibly();
long awaitNanos(long nanosTimeout) throws InterrupttedExceptionI;
boolean await(long time,TimeUnit unit) throws InterrupttedExceptionI;
boolean  awaitUntil(Date deadline)  throws InterrupttedExceptionI;
void signal();
void siganlAll();
AI 代码解读

以上个方法的含义如下:

  • await()方法会使当前线程等待,同时会释放锁,当其他线程中使用signal()或signalAll()方法的时候,线程会重新获得锁继续执行。或者线程被中断是也能跳出等待。
  • awaitUninterruptibly()方法与await()方法基本相同,但是他不会在等待过程中相应或者相应中断。
  • signal()用于唤醒一个在等待中的线程,同理signalAll()用于唤醒所有在等待中的线程。
目录
打赏
0
0
0
0
1
分享
相关文章
流量卡类型及其适用场景
不同流量卡的使用场景可以根据其特点、套餐内容、价格以及用户的具体需求来划分。以下是一些常见的流量卡类型及其适用场景:
基于LoongCollector构建全新可观测Pipeline
LoongCollector是阿里云推出的下一代可观测数据管道,旨在融合多种采集技术,构建统一的可观测数据代理。它具备高性能、可靠性和灵活性,支持日志、指标和追踪等多类型数据采集。通过模块化设计和SPL处理引擎,LoongCollector实现了高效的数据处理与传输,并大幅简化了配置管理。此外,集成eBPF技术,提供无侵入、高性能的应用性能监控,适用于复杂异构环境。未来,LoongCollector将继续优化性能、探索AI赋能的智能化采集。
从 0 到 1 掌握鸿蒙 AudioRenderer 音频渲染:我的自学笔记与踩坑实录(API 14)
本文详细介绍了在 HarmonyOS 中使用 AudioRenderer 开发音频播放功能的完整流程。从环境准备(SDK 5.0.3、DevEco Studio 5.0.7)到核心概念(状态机模型、异步回调),再到开发步骤(实例创建、数据回调、状态控制),结合代码示例与常见问题解决方法,帮助开发者掌握 AudioRenderer 的底层控制与定制化能力。同时,文章还提供了性能优化建议(多线程处理、缓冲管理)及学习路径,附带官方文档和示例代码资源,助你快速上手并避开常见坑点。
242 7
Golang深入浅出之-Go语言指针面试必知:理解与使用指针
【4月更文挑战第21天】Go语言中的指针允许直接操作内存,常用于高效数据共享和传递。本文介绍了指针的基础知识,如声明、初始化和解引用,以及作为函数参数使用。此外,讨论了`new()`与`make()`的区别和内存逃逸分析。在结构体上下文中,指针用于减少复制开销和直接修改对象。理解指针与内存管理、结构体的关系及常见易错点,对于面试和编写高性能Go代码至关重要。
265 2
【MATLAB 】 小波分解信号分解+希尔伯特黄变换+边际谱算法
【MATLAB 】 小波分解信号分解+希尔伯特黄变换+边际谱算法
212 0
centos8 yum安装mysql8 流程配置
centos8 yum安装mysql8 流程配置
921 0
袁志佳:前端全栈工程师精英班
本套课程涵盖大前端的全部领域,并对传统的Web前端全栈深入教学。如利用前端知识开发 AI、VR、AR、iOS、Android、PC、Server、智能硬件。 同时我们将核心打造 JavaScript语言新发展、Vue源码分析、前端持续集成方案汇总、MV*框架深度分析 、前端图形学、NodeJS大规模站点架构、数据结构与算法 极致WebApp性能优化等。
222 4
袁志佳:前端全栈工程师精英班
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问