设计:死锁、哲学家进餐问题

本文探讨了并发环境中的死锁现象,包括死锁的定义、四个必要条件及如何通过Java实现死锁示例。此外,还介绍了如何使用jstack等工具检测死锁。接着,文章详细讨论了哲学家进餐问题,提出了多种解决方案,如限制筷子申请、确保同时拿到两双筷子以及根据编号执行不同动作,以避免死锁的发生。
摘要由CSDN通过智能技术生成

理解死锁

死锁是并发环境下的一种僵持状态。
一组线程中,两部分线程互相等待只有对方才能引起的事件,陷入僵持导致谁都不能够返回。

死锁,这个锁可以是操作系统层面的,也可以是应用层面的,可以是自旋锁,也可以是阻塞锁,我们主要关注它的行为。死锁中的僵持状态,指的就是一个线程上锁失败,执行失败策略——自旋或阻塞,前者是占用CPU的,后者是不占用CPU的。但是它们由于某种原因,无限执行失败策略而不能返回。

引发死锁的四个条件(牢记):
【1】互斥
【2】请求与保持
【3】不可剥夺
【4】循环等待

死锁必须是一个互斥锁,非共享的,这个锁要么owner是A要么是B,非owner想要获得锁就必须等待或询问锁的状态。而且这个锁不能被抢占剥夺,只能被持有者主动释放。而一个线程保持一个互斥锁并请求另外一个互斥锁,同时另一个线程也执行类似的操作,那么便满足上述四个条件,将造成死锁。(同一线程连续执行不可重入代码块也会造成死锁)

写一个死锁

Java中的死锁通常聚焦多线程场景下的死锁,指的是多个线程之间,由于自身持有对方所需要的资源不释放,而等待对方先释放自身所需要的资源,而造成的一种永久阻塞的状态

    static class A implements Runnable{
   
        @Override
        public void run() {
   
            synchronized ("A"){
   
                try {
   
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
   
                    e.printStackTrace();
                }
                synchronized ("B"){
   
                }
            }
        }
    }
    static class B implements Runnable{
   
        @Override
        public void run() {
   
            synchronized ("B"){
   
                try {
   
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
   
          
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值