博客
关于我
并发编程--死锁
阅读量:608 次
发布时间:2019-03-12

本文共 2059 字,大约阅读时间需要 6 分钟。

什么是多线程死锁?

多线程以及多进程改善了系统资源的利用率并提高了系统的处理能力。然而,并发执行也带来了新的问题——死锁。死锁是指多个线程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些线程都将无法向前推进。

死锁主要由两个因素引起:系统资源的竞争和进程推进顺序的不合理。

系统资源的竞争是导致死锁的主要原因之一。许多现代系统都依赖有限的不可剥夺资源(如CPU时间片、磁盘I/O等)来提供服务。这些资源无法同时满足多个进程的需求。如果各进程试图在同一时间请求同一资源,就可能导致死锁。此外,线程间直接调用同步块(如synchronized关键字)也可能引发死锁。

进程推进顺序不合理是另一个导致死锁的主要原因。在并发环境下,进程通常交替地发起和释放资源请求。假设两个进程P1和P2分别持有资源R1和R2,而P1试图请求R2,P2试图请求R1,就有可能出现僵局,导致两者无法继续执行。

以下代码示例展示了一种可能导致死锁的情形:

package com.yxl.demo.ThreadTest;
public class Test5 {
public static void main(String[] args) throws InterruptedException {
TestDemo thread = new TestDemo();
Thread t1 = new Thread(thread, "窗口一");
Thread t2 = new Thread(thread, "窗口二");
t1.start();
Thread.sleep(40);
thread.flag = false;
t2.start();
}
}
class TestDemo implements Runnable {
private volatile int count = 100;
private Object object = new Object();
boolean flag = true;
@Override
public void run() {
if (flag) {
while (count > 0) {
synchronized (object) {
sale();
}
}
} else {
while (count > 0) {
sale();
}
}
}
public synchronized void sale() {
try {
Thread.sleep(50);
} catch (Exception e) {
}
synchronized (object) {
if (count > 0) {
System.out.println(Thread.currentThread().getName() + "出售:" + (100 - count + 1));
count--;
}
}
}
}

在默认情况下,这段代码会导致死锁。运行结果显示,主线程无法正常退出,加锁操作持续存在,导致程序卡顿。

在这个案例中,两个线程都试图在同一锁object上同步操作。线程t1首先获取锁并执行sale(),t2在t1启动后的40ms后启动,并试图获取同一个锁。由于t1仍在占用锁,t2只能等待。此时,若t1释放了锁,t2可能继续执行。然而,原代码的其他逻辑(如flag的设置)导致资源长时间占用,导致死锁发生。

如何解决死锁问题?

解决死锁问题可以采取以下措施:

  • 加锁顺序(Lock Ordering):确保线程在对多个锁加锁时,按照特定顺序操作,避免竞争。

  • 加锁时限(锁定超时):在尝试获取锁时设置超时,超过时间限制后放弃锁请求并释放已经占有的锁。这有助于减少死锁发生的概率。

  • 防止死锁检测(Deadlock Detection):采用他urka检测机制,监测是否存在长时间占锁状态,以便及时处理。现代一些的环境中,这种方法变得越来越常见。

  • 此外,针对上述代码,可以通过调整运行逻辑来避免死锁问题。例如,允许线程在获取锁前先检查资源是否可用。这样可以避免多线程在同一个锁上进行长时间等待,减少死锁风险。

    转载地址:http://dwwaz.baihongyu.com/

    你可能感兴趣的文章
    mysql_secure_installation初始化数据库报Access denied
    查看>>
    MySQL_西安11月销售昨日未上架的产品_20161212
    查看>>
    Mysql——深入浅出InnoDB底层原理
    查看>>
    MySQL“被动”性能优化汇总
    查看>>
    MySQL、HBase 和 Elasticsearch:特点与区别详解
    查看>>
    MySQL、Redis高频面试题汇总
    查看>>
    MYSQL、SQL Server、Oracle数据库排序空值null问题及其解决办法
    查看>>
    mysql一个字段为空时使用另一个字段排序
    查看>>
    MySQL一个表A中多个字段关联了表B的ID,如何关联查询?
    查看>>
    MYSQL一直显示正在启动
    查看>>
    MySQL一站到底!华为首发MySQL进阶宝典,基础+优化+源码+架构+实战五飞
    查看>>
    MySQL万字总结!超详细!
    查看>>
    Mysql下载以及安装(新手入门,超详细)
    查看>>
    MySQL不会性能调优?看看这份清华架构师编写的MySQL性能优化手册吧
    查看>>
    MySQL不同字符集及排序规则详解:业务场景下的最佳选
    查看>>
    Mysql不同官方版本对比
    查看>>
    MySQL与Informix数据库中的同义表创建:深入解析与比较
    查看>>
    mysql与mem_细说 MySQL 之 MEM_ROOT
    查看>>
    MySQL与Oracle的数据迁移注意事项,另附转换工具链接
    查看>>
    mysql丢失更新问题
    查看>>