Java的重入锁定和死锁

有人可以向我解释使用Java代码(伪)例子时Reentrant lockdeadlock是如何相互关联的?


一个可重入的锁定机构允许持有锁的线重新进入关键部分。 这意味着你可以做这样的事情:

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!
}

在非重入锁中,当您尝试从functionOne()调用functionTwo()时,会产生死锁情况,因为线程将不得不等待它保存的锁。

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

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

    th.join();
}

调用线程会尝试等待生成的线程,而该线程在调用方退出之前不会调用deadlock() 。 嘉潮!


一个线程等待一个永远不会发生的情况,就会发生死锁。

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

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.
}

正如你所看到的,一个线程可能调用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!

当隐含的锁正在使用时,自己陷入僵局的尴尬机会。 静态初始化程序块隐式地是线程安全的,因此即使静态初始化程序块未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();
    }
}

你再次陷入僵局!


这里有一个ReentrantLock死锁的例子

class Deadlock {
    private static final ReentrantLock l1 = new ReentrantLock();

    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            public void run() {
                System.out.println("A Trying to lock...");
                l1.lock();
                System.out.println("A Locked...");
                try {
                    Thread t = new Thread(new Runnable() {
                        public void run() {
                            System.out.println("B Trying to lock...");
                            l1.lock();
                            System.out.println("B Must not print");
                            try {
                            } finally {
                                System.out.println("B Trying to unlock...");
                                l1.unlock();
                                System.out.println("B Unlocked...");
                            }
                        }
                    });
                    t.start();
                    try {
                        t.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } finally {
                    System.out.println("A Trying to unlock...");
                    l1.unlock();
                    System.out.println("A Unlocked...");
                }
            }
        });
        t.start();
    }
}

为了解决死锁问题,请注释掉t.join ,并附上try / catch。

链接地址: http://www.djcxy.com/p/41805.html

上一篇: Reentrant lock and deadlock with Java

下一篇: What is a daemon thread in Java?