创建基本的死锁系统
当两个竞争动作等待另一个完成时发生死锁,因此两者都没有。在 java 中,每个对象都有一个锁。为了避免单个对象上的多个线程进行并发修改,我们可以使用 synchronized
关键字,但一切都需要付出代价。错误地使用 synchronized
关键字会导致被称为死锁系统的卡住系统。
考虑在 1 个实例上有 2 个线程工作,让我们将线程调用为 First 和 Second,并且假设我们有 2 个资源 R1 和 R2。首先获得 R1 并且还需要 R2 完成,而 Second 获得 R2 并需要 R1 完成。
所以说在时间 t = 0,
首先是 R1,第二个是 R2。现在第一个是等待 R2 而第二个等待 R1。这种等待是无限期的,这会导致僵局。
public class Example2 {
public static void main(String[] args) throws InterruptedException {
final DeadLock dl = new DeadLock();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
dl.methodA();
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
dl.method2();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
t1.setName("First");
t2.setName("Second");
t1.start();
t2.start();
}
}
class DeadLock {
Object mLock1 = new Object();
Object mLock2 = new Object();
public void methodA() {
System.out.println("methodA wait for mLock1 " + Thread.currentThread().getName());
synchronized (mLock1) {
System.out.println("methodA mLock1 acquired " + Thread.currentThread().getName());
try {
Thread.sleep(100);
method2();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void method2() throws InterruptedException {
System.out.println("method2 wait for mLock2 " + Thread.currentThread().getName());
synchronized (mLock2) {
System.out.println("method2 mLock2 acquired " + Thread.currentThread().getName());
Thread.sleep(100);
method3();
}
}
public void method3() throws InterruptedException {
System.out.println("method3 mLock1 "+ Thread.currentThread().getName());
synchronized (mLock1) {
System.out.println("method3 mLock1 acquired " + Thread.currentThread().getName());
}
}
}
该计划的输出:
methodA wait for mLock1 First
method2 wait for mLock2 Second
method2 mLock2 acquired Second
methodA mLock1 acquired First
method3 mLock1 Second
method2 wait for mLock2 First