1. 简单实现:使用synchronized方法
- Mutual exclusion:互斥访问
- Hold and wait:拥有等待
- Non-emptive:不可剥夺
- Circular waiting:循环等待
package com.fqyuan._11deadlock;
public class DeadLockOri {
private static Object lock1 = new Object();
private static Object lock2 = new Object();
public static void main(String[] args) {
new Thread(new Task1()).start();
new Thread(new Task2()).start();
}
private static class Task1 implements Runnable {
@Override
public void run() {
synchronized (lock1) {
System.out.println("Acquiring the lock1, waiting for lock2...");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock2) {
System.out.println("Acquire both lock1 and lock2 in Task1.");
}
}
}
}
private static class Task2 implements Runnable {
@Override
public void run() {
synchronized (lock2) {
System.out.println("Acquiring the lock2, waiting for lock1...");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock1) {
System.out.println("Acquire both lock2 and lock1 in Task2.");
}
}
}
}
}
2. 利用高级ReentrantLock实现
package com.fqyuan._11deadlock;
import java.util.concurrent.locks.ReentrantLock;
public class DeadLockMore {
public static void main(String[] args) {
SophiscatedTask task = new SophiscatedTask();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
task.process1();
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
task.process2();
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Task {
private Object lock1 = new Object();
private Object lock2 = new Object();
public void process1() {
synchronized (lock1) {
System.out.println("process1:acquired lock1, waiting for lock2.");
synchronized (lock2) {
System.out.println("process1:acquire both");
}
}
}
public void process2() {
synchronized (lock2) {
System.out.println("process2:acquired lock2, waiting for lock1.");
synchronized (lock1) {
System.out.println("process2:acquire both");
}
}
}
}
class SophiscatedTask {
private ReentrantLock lock1 = new ReentrantLock();
private ReentrantLock lock2 = new ReentrantLock();
private void acquireLockWithTry(ReentrantLock lock1, ReentrantLock lock2) {
boolean lock1Status = false;
boolean lock2Status = false;
while (true) {
try {
lock1Status = lock1.tryLock();
lock2Status = lock2.tryLock();
} finally {
if (lock1Status && lock2Status) {
return;
} else if (lock1Status) {
lock1.unlock();
} else if (lock2Status) {
lock2.unlock();
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void acquireLocks(ReentrantLock lock1, ReentrantLock lock2) {
lock1.lock();
System.out.println("Acquire one, waiting for another.");
lock2.lock();
System.out.println("Acquired both.");
}
public void process1() {
try {
acquireLockWithTry(lock1, lock2);
System.out.println("Working in process1");
} finally {
lock1.unlock();
lock2.unlock();
}
}
public void process2() {
try {
acquireLockWithTry(lock2, lock1);
System.out.println("Working in process2");
} finally {
lock1.unlock();
lock2.unlock();
}
}
}