Java 中死锁问题

一、死锁产生的原因

        启动两个线程 监听两个对象, obj1 和 obj2 ,线程1 启动的时候先获得obj1 锁,暂停1s,再去获得obj2的锁,线程2启动的时候先获得obj2锁,在获取obj1的锁

当线程2获取obj2锁再去获得obj1对象的时候,发现obj1被线程1所占用此时就等到,  线程 1 1秒后获得,obj2,被线程2 占用,由于互相持有对方的锁,就会陷入无限的等待。这就产生死锁。回到整个程序代码无法执行下去,占用大量的内存空间,甚至导致系统崩溃。

    private final Object obj1 = new Object();
    private final Object obj2 = new Object();
    private void test1() {
        new Thread(){
            @Override
            public void run() {
                synchronized (obj1){
                    try {
                        System.out.println("ydl---Thread1 obj1");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (obj2){
                        System.out.println("ydl---Thread1 obj2");
                    }
                }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                synchronized (obj2){
                    System.out.println("ydl---Thread2 obj2");
                    synchronized (obj1){
                        System.out.println("ydl---Thread2 obj1");
                    }
                }
            }
        }.start();
    }
    
    //打印结果:
    ydl---Thread1 obj1
    ydl---Thread2 obj2

 

二、死锁产生的条件

        互斥条件 : 一个资源每次只能让一个线城使用

        请求和保持条件:一个线程请求资源阻塞时,不会释放资源

        不剥夺条件:一个线程在执行资源未完成前,不能被剥夺

        循环等待条件: 线程之间形成头尾衔接的循环等待条件。

三、怎么去定位死锁

        jstack 获取线程栈,定位相互之间的依赖关系,进而就可以找到 死锁。

        1.通过jps 和 任务管理器工具确定 进程ID

        2.Jstack 获取线程栈  jstack your-pid 

        3.查看日志

四、解决死锁

        1.最简单的就是 重新启动。但是 这种代价很大,之前的计算工作都会付之东流,

        2.撤销进程,剥夺资源,终止参与死锁的进程,解除死锁。

        3.进程回退:让进程回退到没有死锁的前某一点处,从这个点开始执行。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值