Java|Java--死锁详解
文章图片
文章图片
文章图片
一、定义死锁是指两个或两个以上的进程在执行过程中 , 由于资源竞争或由于彼此通信而造成的阻塞现象 , 若无外力作用 , 他们都将无法推进 。 此时系统处于死锁状态或系统产生了死锁
二、产生原因1)资源竞争
我们知道我们电脑的CPU和主存都属于可剥夺型资源 , 线程争抢CPU的占有 , 来运行线程 。 还有一种属于不可剥夺性资源 , 当系统把这类资源分配给某个线程后 , 就不能强制性收回 , 只有当线程运行完毕后 , 自行释放 。 当我们的线程2想要去调用线程1的不可剥夺性资源时 , 就会产生死锁现象
2)进程之间推进顺序错误
当线程1保持了资源1, 线程2 保持了资源2 , 系统就会处于不安全状态 , 当这两个线程继续向前运行时 , 就可能会发生死锁现象 。 例如线程1想要调用线程2的资源2 , 而线程2也同样想要调用线程1里的资源1.他们都必须等对方的线程执行完毕后 , 释放资源才能继续向下执行 , 这时就会发生死锁现象 。
三、产生死锁的必要条件1).互斥性:线程对资源的占有是排他性 , 一个资源只能被一个线程占有 , 直到释放 。
2)请求和保持条件:一个线程对请求被占有的资源发生阻塞时 , 对已经获得的资源不释放
3)不剥夺:一个线程在释放资源前 , 其他线程无法剥夺占用 。
4) 循环等待:发生死锁时 , 线程进入死循环 , 永久阻塞
四、死锁的解决方法严格意义上来讲 , 我们是不能解决死锁问题的 , 我们只能提前预防 。
1)破坏“请求和保持“条件
当线程已经占有资源后 , 想办法让其不要去竞争那些不可抢占的资源 。
2)破坏“不可抢占”条件
允许进程进行抢占 , 方法一:如果去抢资源被拒绝 , 就释放自己的资源 。 方法二:操作系统允许抢 , 只要你优先级大 , 可以抢
3) 破坏“循环等待”条件
将系统的所有资源统一编号 , 进程可在任意时刻提出申请 , 但所有申请必须按照资源的编号顺序提出
五、死锁的检测
【Java|Java--死锁详解】
六、简单的死锁案例
正常情况下 , 线程1或线程2一个先执行完毕 , 然后另一个开始执行 , 效果如下
但这种结果具有极大的偶然性 , 出现死锁的概率极大 , 则会出现如图所示的情况
代码不会报错 , 但是程序会一直停顿再此 , 无法继续向下执行 , 当然把线程在进入第一个锁时 , 加上睡眠效果更为明显
原因分析:例子中的线程1和线程2就是出现了两个线程相互阻塞的现象 , 线程1需要线程2 释放资源才得以继续进行 , 而线程2也同样如此 。 所以两者就陷入死锁 。
推荐阅读
- Java|计算机专业的本科生,该选择学习Java技术体系还是.NET技术体系
- 小熊回收站|-链表阻塞队列和数组阻塞队列的异同,Java并发编程
- Java|马化腾登顶中国首富,微信、QQ却都免费使用,腾讯到底咋赚钱的?
- Java|为什么美团骑手总是闯红灯昵
- 阿里巴巴|java三大集合遍历方法
- 编程|JAVA基础-网络编程
- Java|Java中的天使和魔鬼:Unsafe类
- Java|面试官:连多线程问题你都一问三不知,还要我怎么“放水”?
- Java|锁--JAVA成长之路
- var|Java应用正加速迁移到Kubernetes