27.ReentrantLock

1.与synchronized不同点:

  • 可中断
  • 可以设置超时时间
  • 可以设置公平锁,公平锁就是为了解决饥饿线程,让线程排队,先进先出,先来的线程先执行。
  • 支持多个条件变量

2.与synchronized相同点都支持锁的可重入

基本格式:

//获取锁
reentrantLock.lock();
try {

} finally {
    //必须释放锁
    reentrantLock.unlock();
}

可重入

同一个线程如果首次获得了这把锁,因为它是这把锁的拥有者,因此有权利再次获取这把锁。

如果是不可重入锁,那么第二次获得锁时,自己也会被锁挡住。

@Slf4j
public class ReentrantLockDemo {
    private static ReentrantLock reentrantLock = new ReentrantLock();

    public static void main(String[] args) {
        //获取锁
        reentrantLock.lock();
        try {
            log.info("调用main方法...");
            method1();
        } finally {
            //必须释放锁
            reentrantLock.unlock();
        }
    }

    public static void method1() {
        reentrantLock.lock();
        try {
            log.info("调用method1方法...");
            method2();
        }finally {
            reentrantLock.unlock();
        }
    }

    public static void method2() {
        reentrantLock.lock();
        try {
            log.info("调用method2方法...");
        }finally {
            reentrantLock.unlock();
        }
    }
}

可被中断

lockInterruptibly方法表示可被打断的锁

lokc方法加锁表示不可被打断的锁

可打断的锁,可以防止死锁。

@Slf4j
public class Reen {
    private static ReentrantLock reentrantLock = new ReentrantLock();

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            try {
                log.info("尝试获取锁....");
                //lockInterruptibly可被打断的锁
                reentrantLock.lockInterruptibly();
            } catch (InterruptedException e) {
                e.printStackTrace();
                log.info("等待获取锁的线程被打断....返回");
                return;
            }
            try {
                log.info("获取到了锁...");
            }finally {
                reentrantLock.unlock();
            }
        }, "t1");

        //main线程获取锁
        reentrantLock.lock();
        t1.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("打断线程t1....");
        t1.interrupt();
    }
}

 可以设置超时时间

tryLock方法,设置超时时间,避免长时间等待,防止死锁。

tryLock方法不设置超时时间参数表示获取不到锁立刻返回。

@Slf4j
public class ReenDemo {

    private static ReentrantLock reentrantLock = new ReentrantLock();

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            //尝试获取锁,时间是立刻返回
            log.info("尝试获取锁...");
            try {
                if(!reentrantLock.tryLock(2, TimeUnit.SECONDS)) {
                    log.info("尝试获取锁失败,返回...");
                    return;
                }
                log.info("尝试获取锁成功...");
            } catch (InterruptedException e) {
                e.printStackTrace();
                log.info("尝试获取锁被打断,返回...");
                return;
            }
            try {

            }finally {
                reentrantLock.unlock();
            }
        }, "t1");

        reentrantLock.lock();
        t1.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        try {
        }finally {
            reentrantLock.unlock();
        }
    }
}

解决哲学家吃饭的死锁问题:

public class DeadLockDemo {

    public static void main(String[] args) {
        Chopstick chopstick1 = new Chopstick("1");
        Chopstick chopstick2 = new Chopstick("2");
        Chopstick chopstick3 = new Chopstick("3");
        Chopstick chopstick4 = new Chopstick("4");
        Chopstick chopstick5 = new Chopstick("5");

        new Philosopher("哲学家1", chopstick1, chopstick2).start();
        new Philosopher("哲学家2", chopstick2, chopstick3).start();
        new Philosopher("哲学家3", chopstick3, chopstick4).start();
        new Philosopher("哲学家4", chopstick4, chopstick5).start();
        new Philosopher("哲学家5", chopstick5, chopstick1).start();
    }
}

@Slf4j
class Philosopher extends Thread {

    //左边的筷子
    Chopstick left;
    //右边的筷子
    Chopstick right;

    public Philosopher(String name, Chopstick left, Chopstick right) {
        super(name);//设置线程名称
        this.left = left;
        this.right = right;
    }

    @Override
    public void run() {
        while (true) {//这里意思是一位哲学家获取了两根筷子后吃完饭,又重新开始下一轮...
            //解决死锁问题,使用ReentrantLock.tryLock方法,避免长时间等待不释放锁的情况
            if(left.tryLock()) {
                try {
                    if(right.tryLock()) {
                        try {
                            eat();
                        }finally {
                            right.unlock();
                        }
                    }
                }finally {
                    left.unlock();
                }
            }


//            synchronized (left) {
//                synchronized (right) {
//                    eat();
//                }
//            }
        }

    }

    private void eat() {
        log.info("eat...");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 筷子类
 */
class Chopstick extends ReentrantLock{

    //名称
    private String name;

    public Chopstick(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Chopstick{" +
                "name='" + name + '\'' +
                '}';
    }
}

公平锁

ReentrantLock模式是非公平锁,synchronized也是非公平锁。但是ReentrantLock可以设置为公平锁。new ReentrantLock(true); 公平锁可以防止饥饿锁。按照先进先出的规则。公平锁会降低并发度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/511844.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

js使用canvas实现画roi功能,并实现交集并集差集操作,附源码

效果概览 支持圆形,矩形,旋转矩形绘制,鼠标像素拾取,图片缩放,图片拖拽,像素测量,roi交集并集补集输出 TODO:实现自由路径绘制,与后台交互数据 实现原理 交集并集差集…

【HTML】标签学习(下.4)

&#xff08;Hello&#xff01;大家好哇&#xff0c;今天我们将继续学习HTML的相关知识&#xff0c;大家可以在评论区进行互动答疑哦~加油&#xff01;&#x1f495;&#xff09; &#xff08;续接【HTML】标签学习&#xff08;下.3&#xff09;&#xff09; 3.4.2 <label&g…

Java设计模式:代理模式的静态和动态之分(八)

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 在软件设计中&#xff0c;代理模式是一种常用的设计模式&#xff0c;它为我们提供了一种方式来控制对原始对象的访问。在Java中&a…

Python快速入门系列-9(Python项目实战)

第九章:Python项目实战 9.1 开发一个简单的Web应用9.1.1 项目概述9.1.2 环境准备9.1.3 项目结构9.1.4 代码实现9.1.4.1 创建数据库模型9.1.4.2 创建视图9.1.4.3 实用工具函数9.1.4.4 运行应用9.1.5 模板设计9.2 数据分析与可视化项目9.2.1 项目概述9.2.2 环境准备9.2.3 数据分…

vulnhub之devguru靶场提权过程(vulnhub打靶日记)

一、环境搭建 VM版本&#xff1a;17.5.1 build-23298084 攻击机&#xff1a;Kali2024&#xff08;下载地址&#xff1a;https://www.kali.org/&#xff09; 靶机&#xff1a;vulnhub靶场Devguru&#xff08;下载地址&#xff1a;https://www.vulnhub.com/entry/devguru-1,62…

探索网红系统功能菜单架构的设计与优化

随着社交媒体和数字化内容的普及&#xff0c;网红经济正在成为新兴的产业。在网红经济体系中&#xff0c;网红系统的功能菜单架构对于平台的用户体验和运营效率至关重要。本文将深入探讨网红系统功能菜单架构的设计与优化&#xff0c;为网红经济的发展提供新的思路和方法。 --…

【Web】记录Polar靶场<困难>难度题一遍过

目录 上传 PHP是世界上最好的语言 非常好绕的命令执行 这又是一个上传 网站被黑 flask_pin veryphp 毒鸡汤 upload tutu Unserialize_Escape 自由的文件上传系统​​​​​​​ ezjava 苦海 你想逃也逃不掉 safe_include CB链 phar PHP_Deserializatio…

Stable Diffusion WebUI 图片信息(PNG Info)

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里&#xff0c;订阅后可阅读专栏内所有文章。 大家好&#xff0c;我是水滴~~ 本文主要讲解 Stable Diffusion WebUI 的图片信息功能&#xff0c;主要包括&#xff1a;获取生成参数、将图片发送到其…

Spark实战:词频统计

文章目录 一、Spark实战&#xff1a;词频统计&#xff08;一&#xff09;Scala版1、分步完成词频统计2、一步搞定词频统计 &#xff08;二&#xff09;Python版1、分步完成词频统计2、一步搞定词频统计 二、实战总结 一、Spark实战&#xff1a;词频统计 &#xff08;一&#x…

【黑马头条】-day05延迟队列文章发布审核-Redis-zSet实现延迟队列-Feign远程调用

文章目录 昨日回顾今日内容1 延迟任务1.1 概述1.2 技术对比1.2.1 DelayQueue1.2.2 RabbitMQ1.2.3 Redis实现1.2.4 总结 2 redis实现延迟任务2.0 实现思路2.1 思考2.2 初步配置实现2.2.1 导入heima-leadnews-schedule模块2.2.2 在Nacos注册配置管理leadnews-schedule2.2.3 导入表…

STM32应用开发——使用PWM+DMA驱动WS2812

STM32应用开发——使用PWMDMA驱动WS2812 目录 STM32应用开发——使用PWMDMA驱动WS2812前言1 硬件介绍1.1 WS2812介绍1.1.1 芯片简介1.1.2 引脚描述1.1.3 工作原理1.1.4 时序1.1.5 传输协议 1.2 电路设计 2 软件编程2.1 软件原理2.2 测试代码2.2.1 底层驱动2.2.2 灯效应用 2.3 运…

css实现更改checkbox的样式;更改checkbox选中后的背景色;更改checkbox选中后的icon

<input class"check-input" type"checkbox"> .check-input {width: 16px;height: 16px;} /* 设置默认的checkbox样式 */input.check-input[type"checkbox"] {-webkit-appearance: none; /* 移除默认样式 */border: 1px solid #999;outl…

go连接数据库(原生)

根据官网文档 Go Wiki: SQL Database Drivers - The Go Programming Language 可以看到go可以连接的关系型数据库 ​ 常用的关系型数据库基本上都支持&#xff0c;下面以mysql为例 下载mysql驱动 打开上面的mysql链接 GitHub - go-sql-driver/mysql: Go MySQL Driver i…

【已解决】Error: error:0308010C:digital envelope routines::unsupported

前言 场景&#x1f3ac; 使用 Ant Design &#xff0c; 执行 npm run dev 出现异常。 文章目录 前言场景&#x1f3ac; 异常信息解决方案方案一(推荐)MAC | Linux 电脑成功⬇️ Windows 电脑 方案2&#xff1a; 不懂留言 JavaPub 异常信息 我直接异常信息&#xff0c;你可以…

Python快速入门系列-8(Python数据分析与可视化)

第八章:Python数据分析与可视化 8.1 数据处理与清洗8.1.1 数据加载与查看8.1.2 数据清洗与处理8.1.3 数据转换与整理8.2 数据可视化工具介绍8.2.1 Matplotlib8.2.2 Seaborn8.2.3 Plotly8.3 数据挖掘与机器学习简介8.3.1 Scikit-learn8.3.2 TensorFlow总结在本章中,我们将探讨…

【嵌入式智能产品开发实战】(十五)—— 政安晨:通过ARM-Linux掌握基本技能【GNU C标准与编译器】

目录 GNU C 什么是C语言标准 C语言标准的内容 C语言标准的发展过程 1.K&R C 2.ANSI C 3.C99标准 4.C11标准 编译器对C语言标准的支持 编译器对C语言标准的扩展 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: 嵌入式智能产品…

QA测试开发工程师面试题满分问答6: 如何判断接口功能正常?从QA的角度设计测试用例

判断接口功能是否正常的方法之一是设计并执行相关的测试用例。下面是从测试QA的角度设计接口测试用例的一些建议&#xff0c;包括功能、边界、异常、链路、上下游和并发等方面&#xff1a; 通过综合考虑这些测试维度&#xff0c;并设计相应的测试用例&#xff0c;可以更全面地评…

【机器学习】“强化机器学习模型:Bagging与Boosting详解“

1. 引言 在当今数据驱动的世界里&#xff0c;机器学习技术已成为解决复杂问题和提升决策制定效率的关键工具。随着数据的增长和计算能力的提升&#xff0c;传统的单一模型方法已逐渐无法满足高精度和泛化能力的双重要求。集成学习&#xff0c;作为一种结合多个学习算法以获得比…

大数据实验二-HDFS编程实践

一&#xff0e;实验内容 HDFS编程实践&#xff1a; 1&#xff09;使用HDFS文件操作的常用Shell命令&#xff1b; 2&#xff09;利用Hadoop提供的Java API进行基本的文件操作。 二&#xff0e;实验目的 1、理解HDFS在Hadoop体系结构中的角色。 2、熟练使用HDFS操作常用的Sh…

【测试篇】接口测试

接口测试&#xff0c;可以用可视化工具 postman。 如何做接口测试&#xff1f;&#xff1f; 我们可以先在浏览器中随机进入一个网页&#xff0c;打开开发者工具&#xff08;F12&#xff09;。 随便找一个接口Copy–>Copy as cURL(bash) 打开postman 复制地址 进行发送。 …