两把锁死锁的可能性?

时间:2019-08-07 15:39:43

标签: java concurrency locking

此代码是否可以通过线程1调用one和线程2调用two死锁。也就是说,能否将内部锁的获取重新排序到获取外部锁之前(从另一个线程的POV)?

private final Object foo = new Object();
synchronized  void one() {
    // ...
    synchronized(this.foo) {
       // ...
    }
    // ...
}

synchronized void two() {
    // ...
    synchronized(this.foo) {
       // ...
    }
    // ...
}

2 个答案:

答案 0 :(得分:0)

不,这不会死锁。

调用同步方法时,this的固有锁定在执行方法主体之前被锁定。在这里,线程1或线程2将开始运行其方法,而另一个线程将无法锁定this.foo的固有锁定,因此this的锁定所有者将能够锁定this.foo

答案 1 :(得分:0)

使用简单测试即可:

class LockTest implements Runnable {
    public final Object foo = new Object();
    boolean runOne;

    public LockTest(boolean runOne) {
        this.runOne = runOne;
    }

    synchronized void  one() {
        System.out.println("runnin one function");
        synchronized(this.foo) {
            try {
                System.out.println("Enter Sleep function one");
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    synchronized void  two() {
        System.out.println("running two function");
        synchronized(this.foo) {
            try {
                System.out.println("enter sleep function two");
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void run() {
        if(runOne)
        one();
        else
            two();
    }
}

在主类中使用它:

while (true)
        {
            LockTest document2 = new LockTest(true);
            LockTest document3 = new LockTest(false);
            Thread tread1 = new Thread(document2);
            Thread tread2 = new Thread(document3);
            tread1.start();
            tread2.start();
            a++;
            if(a==10)
                break;

        }

我们没有锁定,甚至没有通过线程转储观看一切正常。为什么?因为每次我们都用一个新的对象foo初始化一个新的线程。但是,如果将该对象声明为静态对象,则它将是一个锁,其他线程需要等待。所以从我的测试和POV来看。不,它不能陷入僵局。