Mat*_* B. 8 java deadlock locking reentrancy
谁能向我解释如何Reentrant lock和deadlock相互关系与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()者退出之前,该线程无法调用.嘉潮!
发生死锁然后线程等待永远不会发生的情况.
显而易见的情况是,当您尝试锁定两个锁时,由不同的线程以不同的顺序锁定.
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)
你又陷入了僵局!
| 归档时间: |
|
| 查看次数: |
10370 次 |
| 最近记录: |