25.死锁

一个线程如果需要同时获取多把锁,就容易产生死锁。

t1线程获得A对象锁,接下来想获取B对象的锁。

t2线程获得B对象锁,接下来想获取A对象的锁。

/**
     * 死锁demo
     * @param args
     */
    public static void main(String[] args) {
        Object a = new Object();
        Object b = new Object();
        new Thread(() -> {
            synchronized (a) {
                log.info("lock a");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (b) {
                    log.info("lock b...");
                }
            }
        }, "t1").start();

        new Thread(() -> {
            synchronized (b) {
                log.info("lock b");
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (a) {
                    log.info("lock a...");
                }
            }
        }).start();
    }

使用工具定位死锁:

cmd下的jps命令,可以查看当前正在运行的java进程

工具一:jstack命令 

可以定位到具体的代码行数: 

工具二:jconsole

经典死锁案例:五位哲学家五根筷子吃饭

public class DeadLockDemo {

    public static void main(String[] args) {
        Chopstick chopstick1 = new Chopstick("1");
        Chopstick chopstick2 = new Chopstick("2");
        Chopstick chopstick3 = new Chopstick("3");
        Chopstick chopstick4 = new Chopstick("4");
        Chopstick chopstick5 = new Chopstick("5");

        new Philosopher("哲学家1", chopstick1, chopstick2).start();
        new Philosopher("哲学家2", chopstick2, chopstick3).start();
        new Philosopher("哲学家3", chopstick3, chopstick4).start();
        new Philosopher("哲学家4", chopstick4, chopstick5).start();
        new Philosopher("哲学家5", chopstick5, chopstick1).start();
    }
}

@Slf4j
class Philosopher extends Thread {

    //左边的筷子
    Chopstick left;
    //右边的筷子
    Chopstick right;

    public Philosopher(String name, Chopstick left, Chopstick right) {
        super(name);//设置线程名称
        this.left = left;
        this.right = right;
    }

    @Override
    public void run() {
        while (true) {//这里意思是一位哲学家获取了两根筷子后吃完饭,又重新开始下一轮...
            synchronized (left) {
                synchronized (right) {
                    eat();
                }
            }
        }

    }

    private void eat() {
        log.info("eat...");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 筷子类
 */
class Chopstick {

    //名称
    private String name;

    public Chopstick(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Chopstick{" +
                "name='" + name + '\'' +
                '}';
    }
}

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卷土重来…

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值