java死锁

死锁:指俩个或以上的线程循环等待其他线程占用的资源,但在未获取资源时又不放弃自己的资源。这种情况下如果没有外力作用,将永远等待下去。
比如:有A ,B两个资源,甲,乙两个线程。
甲——>A 甲占有A
乙——>B 乙占有B
这时候甲请求B,乙请求A,但是甲没请求到B的时候又不愿放弃A,乙没请求到A的时候不愿放弃B。两个进程都不能正常执行,这样两者就会无限的等待下去。
产生死锁的条件:
1:互斥条件。某个资源某刻只能由一个线程占用。
2:不可抢占条件。进程所获得资源在未使用完毕之前,资源申请者不能强行获取。
3:占用申请条件。
4:循环等待条件。
以上四个条件同时发生,即会产生死锁。
我们来看一下具体例子:

class Suo {
    static Object so1 = new Object();
    static Object so2 = new Object();
}

class DeadLocks implements Runnable {
    public boolean flag;
    public DeadLocks(boolean flag) {
        this.flag = flag;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        if (flag) {
            while (true) {
                synchronized (Suo.so1) {//请求到so1并加锁
                    System.out.println("so1:"+ Thread.currentThread().getName());
                    synchronized (Suo.so2) {//请求so2,并加锁,由于so2被占用,故会一直等待
                        System.out.println("so2:"+ Thread.currentThread().getName());
                    }
                }
            }
        } else {
            while (true) {
                synchronized (Suo.so2) {//请求到so2并加锁
                    System.out.println("so2:"+ Thread.currentThread().getName());
                    synchronized (Suo.so1) {//请求到so1并加锁,由于so1被占用,故会一直等待
                        System.out.println("so1:"+ Thread.currentThread().getName());
                    }
                }
            }
        }
    }
}

测试:

public class JstackDemo {

    public static void main(String[] args) {
        Thread t1 = new Thread(new DeadLocks(true));
        Thread t2 = new Thread(new DeadLocks(false));
        t1.start();
        t2.start();
    }
}

输出:
so1:Thread-0
so2:Thread-1

只打印两行,就不在打印下去了。
我们使用jstack打印下jvm堆栈信息
这里写图片描述
直接就可以看出:在34行和45发生死锁。

那么如何避免死锁呢。
只要打破上述四个条件之一就可解除死锁。
算法:银行家算法。

死锁的恢复:
1系统重启。
2撤销进程,剥夺资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值