Java的重入锁和死锁

Mat*_* B. 8 java deadlock locking reentrancy

谁能向我解释如何Reentrant lockdeadlock相互关系与Java代码(伪)的例子吗?

ste*_*vls 13

可重入锁定机构允许持有锁的线重新进入临界区.这意味着您可以执行以下操作:

public synchronized void functionOne() {

    // do something

    functionTwo();

    // do something else

    // redundant, but permitted...
    synchronized(this) {
        // do more stuff
    }    
}

public synchronized void functionTwo() {
     // do even more stuff!
}
Run Code Online (Sandbox Code Playgroud)

在非重入锁定中,当您尝试调用时会出现死锁情况functionTwo(),functionOne()因为线程必须等待锁定...它自己保持锁定.

当然,死锁是线程1持有锁A并等待锁B而线程2保持锁B并等待锁A的恶劣情况.因此,两者都不能继续.此代码示例创建了一个死锁:

public synchronized void deadlock() throws InterruptedException {
    Thread th = new Thread() {
        public void run() {
            deadlock();
        }
    }.start();

    th.join();
}
Run Code Online (Sandbox Code Playgroud)

调用线程尝试等待生成的线程,在调用deadlock()者退出之前,该线程无法调用.嘉潮!


Pet*_*rey 6

发生死锁然后线程等待永远不会发生的情况.

显而易见的情况是,当您尝试锁定两个锁时,由不同的线程以不同的顺序锁定.

ReentrantLock lock1 = new ReentrantLock();
ReentrantLock lock2 = new ReentrantLock();

public void methodA() {
    lock1.lock();
    lock2.lock();
    // do something and un lock both.
}

public void methodB() {
    lock2.lock();
    lock1.lock();
    // do something and un lock both.
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,线程可以调用methodA并获取lock1等待lock2,另一个线程调用methodB并获取lock2等待lock1.


但是,线程可能会自行死锁.一个例子是ReentrantReadWriteLock,因为它不支持将读锁升级为写锁.

ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
rwl.readLock().lock();
// do we need to update?
rwl.writeLock().lock(); // will wait for the readLock() to be released!
Run Code Online (Sandbox Code Playgroud)

隐藏锁使用时,一个让自己陷入僵局的难以理解的机会.静态初始化块是隐式线程安全的,因此即使静态初始化块不是,也会使用锁定synchronized

class A {
     private static int VALUE;
     static {
        Thread t = new Thread() {
            public void run() {
                // waits for the A class to load.
                VALUE = someLongTask();
            }
        };
        t.start();
        // waits for the thread.
        t.join();
    }
}
Run Code Online (Sandbox Code Playgroud)

你又陷入了僵局!