首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java线程面试题:什么是死锁?如何避免?

Java线程面试题:什么是死锁?如何避免?

作者头像
GeekLiHua
发布2025-01-21 15:06:21
发布2025-01-21 15:06:21
1780
举报
文章被收录于专栏:JavaJava

Java线程面试题:什么是死锁?如何避免?

死锁是指两个或多个线程相互等待对方持有的锁而不能继续执行,造成代码无法向下进行的情况。以下是一个简单的例子:

代码语言:javascript
复制
public class DeadLockDemo {
    private static final Object lockA = new Object();
    private static final Object lockB = new Object();

    public static void main(String[] args) {
        Thread threadA = new MyThreadA();
        Thread threadB = new MyThreadB();
        threadA.start();
        threadB.start();
    }

    static class MyThreadA extends Thread {
        @Override
        public void run() {
            synchronized (lockA) {
                System.out.println("MyThreadA acquired lockA");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("MyThreadA is waiting for lockB...");
                synchronized (lockB) {
                    System.out.println("MyThreadA acquired lockB");
                }
            }
        }
    }

    static class MyThreadB extends Thread {
        @Override
        public void run() {
            synchronized (lockB) {
                System.out.println("MyThreadB acquired lockB");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("MyThreadB is waiting for lockA...");
                synchronized (lockA) {
                    System.out.println("MyThreadB acquired lockA");
                }
            }
        }
    }
}

在这个例子中,我们创建了两个线程:MyThreadAMyThreadB,分别竞争获取 lockAlockB 这两个对象的锁。MyThreadA获取到了lockA 的锁,进入临界区并休眠1秒钟,然后试图获取 lockB 的锁;而 MyThreadB 获取到了lockB 的锁,也进入临界区并休眠1秒钟,然后试图获取 lockA 的锁。由于两个线程都在等待对方释放所持有的锁,因此出现了死锁情况。

避免死锁一般采用以下策略:

  1. 避免使用多个同步锁,尽量减少竞争情况;
  2. 保证获取锁的顺序,从而避免循环依赖;
  3. 使用定时锁来限制等待时间,超过一定时间后释放资源重新尝试获取。

修改代码如下:

代码语言:javascript
复制
public class DeadLockDemo {
    private static final Object lockA = new Object();
    private static final Object lockB = new Object();

    public static void main(String[] args) {
        Thread threadA = new MyThreadA();
        Thread threadB = new MyThreadB();
        threadA.start();
        threadB.start();
    }

    static class MyThreadA extends Thread {
        @Override
        public void run() {
            synchronized (lockA) {
                System.out.println("MyThreadA acquired lockA");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("MyThreadA is waiting for lockB...");
                synchronized (lockB) {
                    System.out.println("MyThreadA acquired lockB");
                }
            }
        }
    }

    static class MyThreadB extends Thread {
        @Override
        public void run() {
            //保证获取锁的顺序,从而避免循环依赖
            synchronized (lockA) {
                System.out.println("MyThreadB acquired lockA");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("MyThreadB is waiting for lockB...");
                synchronized (lockB) {
                    System.out.println("MyThreadB acquired lockB");
                }
            }
        }
    }
}

MyThreadB 中修改了竞争锁的获取顺序,使其先获取 lockA 的锁,从而解除了死锁情况。

总结:死锁是一种常见的并发问题,可以通过避免使用多个同步锁、保证获取锁的顺序和使用定时锁等策略来避免。在进行并发编程时,应当尽量避免出现死锁问题,以保障程序运行的稳定性和正确性。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-06-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Java线程面试题:什么是死锁?如何避免?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档