Java-关于死锁

189 阅读2分钟

什么是死锁?

个人理解: 当两个线程互相竞争自己持有的资源的时候,就产生了所谓的死锁。

例如 A拿着苹果,B拿着香蕉。A想吃到苹果的时候也吃到香蕉, 而反观B想吃到香蕉也同时吃到苹果,两人互不礼让

代码解释

首先创建一个资源类,并且实现Runnable接口。

资源分别有两个 定义为 lockA lockB 。

class MyThread implements Runnable{

    //资源
    private String lockA;
    private String lockB;
    //带参构造初始化
    MyThread(String lockA,String lockB){
        this.lockA = lockA;
        this.lockB = lockB;
    }
    //先省略run方法

然后如刚才的例子所说,当线程拿到lockA的时候,我们希望它不会释放lockA并且去试图竞争lockB,反观另一个线程也是如此

因此我们的run方法写法如下:

@Override
    public void run() {
//这里的lockA不是字面上的lockA 例如当Mythread中的带参构造中传入不同的值 下面这个lockA也会相对应的改变 
//new Mythread(lockB,lockA) ,这样的话此时的lockA就= lockB lockB就=lockA 见上面的带参初始化
        synchronized(lockA){
            System.out.println("我是Lock"+Thread.currentThread().getName()+"我枪到了"+lockA+"锁 现在即将拿"+lockB+"锁....");
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (lockB){
                System.out.println("永远拿不到的锁");
            }
        }
    }

主方法代码:

public class deadLockDemo {
    public static void main(String[] args) {

        String lockA = "lockA";
        String lockB = "lockB";

        //开始两个线程分别竞争需要的资源
        //第一个线程进去拿到了lockA对象的锁
        new Thread(new MyThread(lockA,lockB),"A").start();
        //第二个线程进去拿到了lockB对象的锁
        new Thread(new MyThread(lockB,lockA),"B").start();
    }
}

结果: image.png

如何查看死锁?

使用两个命令。

jps -l (ps在linux是查看进程的命令),可以看到当前在运行的deadLockDemo进程号。

image.png

接着执行 jstack 进程号 查看进程信息,找到死锁问题。

image.png 打印了一大串。。。 此时滑下去看最底部

image.png 显示的死锁导致的原因,方便我们定位排查。

此文为个人笔记。。。