• 【面试:并发篇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.多把锁的优缺点

    优点

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

    缺点

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

  • 相关阅读:
    2011年01月25日 Go生态洞察:Go与JSON的高效结合
    坚持与确定性:毒药还是良药?
    HY57V561620FTP_SDRAM文档总结
    2022年最新阿里Java高级岗200+面试题,能答出一般你就进了
    漏刻有时数据可视化Echarts组件开发(32):温度计2
    【浅学Java】Seervlet小项目——MessageWall
    java高校科研项目管理系统计算机毕业设计MyBatis+系统+LW文档+源码+调试部署
    Redis - 对象结构
    SpringSecurity原理解析(五):HttpSecurity 类处理流程
    VScode开发STM32/GD32单片机-环境搭建
  • 原文地址:https://blog.csdn.net/m0_71229547/article/details/125910529