首页 > 其他分享 >27.ReentrantLock

27.ReentrantLock

时间:2024-04-02 23:33:18浏览次数:17  
标签:27 log reentrantLock Chopstick try new public 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); 公平锁可以防止饥饿锁。按照先进先出的规则。公平锁会降低并发度。

标签:27,log,reentrantLock,Chopstick,try,new,public,ReentrantLock
From: https://blog.csdn.net/qq_36352889/article/details/137292962

相关文章

  • 2024年4月2日第27篇博客
    今天解决了一个关于OKhtt引入的问题关于okhttp3找不到导入文件创建network_config.xml文件<?xmlversion="1.0"encoding="utf-8"?><network-security-configxmlns:tools="http://schemas.android.com/tools"><base-configcleartextTrafficPermi......
  • 2-27. 背包物品选择高亮显示和动画
    本节目标实现点击背包中的格子之后,格子会有高亮的效果开始实现修改SlotUI这样写的话,如果有两个格子被点击,那么两个格子都会高亮,这是我们不希望看到的继续修改SlotUI修改InventoryUI给高亮增加动画然后把图片添加到动画里面项目相关代码代码仓库:https://gitee......
  • 高精度、低功耗、小封装电压检测芯片 HXWSEMI桦芯微HX61CC2202MR、HX61CC2702MR、HX61
    HX61C系列芯片是使用CMOS技术开发的高精度、低功耗、小封装电压检测芯片。检测电压在小温度漂移的情况下保持极高的精度。客户可选择CMOS输出或OpenDrain输出。■产品特点高精度:±2%低功耗:2.0µA(Vin=1.5V)检测电压范围:1.0V~6.0V,100mV步进工作电压范围:0.7V......
  • 3.27毕设
    由于采用前后端分离的方式进行开发,不同的端口必将导致跨域问题这里我找到了两种解决方式第一种,在Controller类需要的方法上面中加入@CrossOrigin注解 可以查到,但是如果方法很多的话,每一个都要加注解,很麻烦,不推荐 所以应该考虑到用配置类 同样是可以解决问题的,属于一劳......
  • 第27届法国野生生物与自然摄影节(国际知名的自然类摄影专题大赛之一,免报名费。4月28日
    一、赛事简介法国野生生物与自然摄影节是国际知名的自然类摄影专题大赛之一,今年已是第27届。摄影节将于2024年11月21日-24日在法国上马恩省的蒙蒂埃恩德举行。该摄影节起源于1996年,当地的摄影爱好者举办了一场WPY(野生生物摄影师年赛)的摄影展并迅速走红,于第二年发展成为一个国际......
  • 2024 蓝桥打卡Day27
    D27ccfcsp代码练习材料整理Java中数组复制1.使用clone()方法2.使用System.arraycopy()方法四舍五入Arrays类进制转换十进制转其他进制其他进制转换为十进制保留小数位数使用String.format()使用DecimalFormat的format()方法使用String.formatArrayListHash......
  • 洛谷题单指南-图的基本应用-P1127 词链
    原题链接:https://www.luogu.com.cn/problem/P1127题意解读:按字典序排列单词,使得相邻单词的首位字母一样。解题思路:由于单词之间可以相邻的条件是前一个单词的末尾字母和后一个单词的开头字母一样,因此可以遍历每一个单词,再找到每一个可以接在其后面的单词,建立一个邻接表,然后从......
  • [数据集][目标检测]道路行人车辆坑洞锥形桶检测数据集VOC+YOLO格式6275张4类别
    数据集格式:PascalVOC格式+YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件)图片数量(jpg文件个数):6275标注数量(xml文件个数):6275标注数量(txt文件个数):6275标注类别数:4标注类别名称:["car","person","pothole","trafficcone......
  • 3121002754 刘栋 《需求规格说明书》
    这个作业属于哪个课程<软件工程2024-双学位>这个作业要求在哪里<团队作业2——需求说明文档>这个作业的目标完成需求文档目录团队作业2-需求说明文档需求说明面向用户分析功能性需求预期用户数量系统价值gitcode链接时间安排原安排表校正后安排感想团队作业2-......
  • 春秋云镜 CVE-2023-27179
    靶标介绍:GDideesCMSv3.9.1及更低版本被发现存在本地文件泄露漏洞,漏洞通过位于/_admin/imgdownload.php的filename参数进行利用。访问实验地址通过靶场介绍得知,漏洞通过位于/_admin/imgdownload.php的filename参数进行利用。构造访问目录。http://eci-2zeh4jwpx8......