• 【面试:并发篇20:多线程:多把锁问题】


    【面试:并发篇20:多线程:多把锁问题】

    00.前言

    如果有任何问题请指出,感谢。

    01.介绍

    我们现在有这么一个问题,有一个房子 有卧室和书房,书房可以用来学习 卧室可以用来睡觉,但是学习和睡觉两件事不冲突,不过学习和学习直接冲突 睡觉和睡觉冲突。这个就是我们的问题,如果仅仅只有房子这一把锁,势必会导致 睡觉的时候 房子被占用 不能用来学习,显然是不合适的。

    02.案例

    public class TestMultiLock {
        public static void main(String[] args) {
            BigRoom bigRoom = new BigRoom();
            new Thread(() -> {
                bigRoom.study();
            },"小南").start();
            new Thread(() -> {
                bigRoom.sleep();
            },"小女").start();
        }
    }
    
    @Slf4j(topic = "c.BigRoom")
    class BigRoom {
        public void sleep() {
            synchronized (this) {
                log.debug("sleeping 2 小时");
                Sleeper.sleep(2);
            }
        }
    
        public void study() {
            synchronized (this) {
                log.debug("study 1 小时");
                Sleeper.sleep(1);
            }
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    结果

    00:23:51.597 c.BigRoom [小南] - study 1 小时
    00:23:52.607 c.BigRoom [小女] - sleeping 2 小时

    解释
    可以看出小南与小女都想使用这个屋子,但是小南先抢到 学习了1h后小南才开始睡2h,但是就如我们题目描述 睡觉与学习没有关系 理论上 他俩应该同时开始。

    03.解决方案

    public class TestMultiLock {
        public static void main(String[] args) {
            BigRoom bigRoom = new BigRoom();
            new Thread(() -> {
                bigRoom.study();
            },"小南").start();
            new Thread(() -> {
                bigRoom.sleep();
            },"小女").start();
        }
    }
    
    @Slf4j(topic = "c.BigRoom")
    class BigRoom {
    
        private final Object studyRoom = new Object();
    
        private final Object bedRoom = new Object();
    
        public void sleep() {
            synchronized (bedRoom) {
                log.debug("sleeping 2 小时");
                Sleeper.sleep(2);
            }
        }
    
        public void study() {
            synchronized (studyRoom) {
                log.debug("study 1 小时");
                Sleeper.sleep(1);
            }
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    结果

    00:27:56.494 c.BigRoom [小南] - study 1 小时
    00:27:56.494 c.BigRoom [小女] - sleeping 2 小时

    解释
    我们在BigRoom类中又创建了两个 对象 分别是studyRoom、bedRoom作为学习与睡觉的锁,这就是用多把锁来解决这个问题。

    04.多把锁的优缺点

    优点

    优点很明显,细分了锁的粒度 可以增强并发度

    缺点

    缺点是,如果一个线程需要同时获得多把锁,那就容易发生死锁

  • 相关阅读:
    操作系统第三周
    buuctf [BJDCTF2020]Easy MD5
    Css 3 动画
    2023.10.20
    Java智慧工地SaaS管理平台源码:AI/云计算/物联网
    mysql 反斜杠\的坑
    Matlab图像处理-读入图像
    Codeforces 398C LRU (概率dp)
    ESP8266-Arduino网络编程实例-接入WiFi网络
    集合的父亲之Map------(双列集合顶级接口)和遍历方式
  • 原文地址:https://blog.csdn.net/m0_71229547/article/details/125910529