java死锁简单案例

本文深入探讨了Java中的线程死锁问题,通过哲学家就餐问题阐述了死锁的产生条件。此外,还介绍了在遍历集合如map或list时,如果在循环中直接删除元素会抛出`ConcurrentModificationException`,并解释了其内部机制。解决这类问题的最佳实践是使用迭代器进行删除操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

每天一个小tip:map或者List等集合在循环下需要remove元素时,采用迭代器进行,因为需要进行checkForComodification,即对应一下modCount,实际每一次操作集合时,都会对modCount+1,当modCount大小不等于expectedModCount时,抛出ConcurrentModificationException(),回到正文~~~~

1、线程死锁的概念:

我们都知道,线程在执行的过程中是占着CPU的资源的,当多个线程都需要一个被锁住的条件才能结束的时候,死锁就产生了!

还有一个经典的死锁现象:
经典的“哲学家就餐问题”,5个哲学家吃中餐,坐在圆卓子旁。每人有5根筷子(不是5双),每两个人中间放一根,哲学家时而思考,时而进餐。每个人都需要一双筷子才能吃到东西,吃完后将筷子放回原处继续思考,如果每个人都立刻抓住自己左边的筷子,然后等待右边的筷子空出来,同时又不放下已经拿到的筷子,这样每个人都无法得到1双筷子,无法吃饭都会饿死,这种情况就会产生死锁:
每个人都拥有其他人需要的资源,同时又等待其他人拥有的资源,并且每个人在获得所有需要的资源之前都不会放弃已经拥有的资源。当多个线程完成功能需要同时获取多个共享资源的时候可能会导致死锁。

1:两个任务以相反的顺序申请两个锁,死锁就可能出现

2:线程T1获得锁L1,线程T2获得锁L2,然后T1申请获得锁L2,同时T2申请获得锁L1,此时两个线程将要永久阻塞,死锁出现

如果一个类可能发生死锁,那么并不意味着每次都会发生死锁,只是表示有可能。要避免程序中出现死锁。

3:要避免死锁某个程序需要访问两个文件,当进程中的两个线程分别各锁住了一个文件,那它们都在等待对方解锁另一个文件,而这永远不会发生。
总结:双方都在等待对方解锁,而自己也占有着对方想要的锁。死锁产生的必要条件:第一个就是线程之间必须互斥,一个资源只能一条线程用,比如其中一根筷子,a占有了,b就不能占有(但是b可能想占有,这就导致了死锁的其中一个必要条件),第二个就是线程因为占有着该资源而阻塞,因为想去获取别人的资源,但别人没有释放。第三个条件就是,你所获得的资源不想释放,那别人也得到不了。第四个条件就是循环等待,就比如刚刚的例子里面,形成了一个圆,收尾相互需要资源,形成一个环

2、简单举例说明:

// 互相想占用对方的资源,ab形成循环,互斥,不释放对方拿不到
public static void main(String[] args) {
        // deadLock
        Object a = new Object();
        Object b = new Object();
        new Thread(() -> {
            synchronized (a) {
                System.out.println("get a");
                try {
                    Thread.sleep(Long.parseLong("1000"));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (b) {
                    System.out.println("want get b");
                }
            }
        }, "a").start();

        new Thread(() -> {
            synchronized (b) {
                System.out.println("get b");
                try {
                    Thread.sleep(Long.parseLong("1000"));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (a) {
                    System.out.println("want get a");
                }
            }
        }, "b").start();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值