死锁的原因和避免死锁的常见方法

内容来自《java并发编程的艺术》

  死锁是啥呢?
  上一段代码:

public class DeadLockDemo {
    private static String A = "A";
    private static String B = "B";
    public static void main(String[] args) {
        new DeadLockDemo().deadLock();
    }
    private void deadLock() {
        Thread t1 = new Thread(new Runnable() {
            @Override public void run() {
                //先锁住A这个对象
                synchronized (A) { try {
                    //睡眠2000毫秒
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    //然后去获取B对象的锁,此时B对象的锁已经被线程t2获得,如果t2不释放锁的话t1是获取不到的
                }synchronized (B) {
                    System.out.println("1");
                }
                }
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override public void run() {
                //先锁住B这个对象
                synchronized (B) {
                    //然后去获取A对象的锁,此时A对象的锁已经被线程t1获得,如果t1不释放锁的话t2也获取不到
                    synchronized (A) { System.out.println("2");
                }
                }
            }
        }); t1.start(); t2.start(); }
}


  应该能看明白,看不明白就复制到idea跑一下。

  死锁通俗来说就是线程资源冲突,比如在并发的情况下A线程获得了资源1它接下来需要资源2,同时B线程获得了资源2接下来需要资源1,这时线程A没有获得所需资源不会释放,同样,线程B也是如此,两个线程就会阻塞,如果不设置锁超时过期就会出现一直死锁的情况,在真实开发环境这种情况是很致命的(当然一般测试环境这种代码就被kill了)。

  下面说几个在书里看到的避免死锁的常见方法:

  1.避免一个线程获得多个锁

  2.避免一个线程在锁内同时占用多个资源,尽量一个锁至占用一个资源

  3.尝试使用定时锁,使用lock.tryLock(timeout)来代替内部锁

  4.对于数据库锁,加锁解锁必须在一个数据库连接里,不然会出现解锁失败的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值