下面死锁发生是一个假象,因为两个线程启动,两个线程中都存在两个对象o1,o2。因为死锁发生的条件是竞争资源,那么两个线程中都存在两个对象,哪里来的竞争,只不过是一个假象。
package com.caojiulu.runnable;
public class DeadLock {
public static void main(String[] args) {
ResouceLocktask resouceLocktask = new ResouceLocktask();
new Thread(resouceLocktask, "线程A").start();
new Thread(resouceLocktask, "线程B").start();
}
}
class ResouceLocktask implements Runnable{
private Object o1 = new Object();
private Object o2 = new Object();
private boolean flag = true;
@Override
public void run() {
if(flag){
flag = false;
synchronized (o1) {
System.out.println(Thread.currentThread().getName()+"锁住资源o1,等到o2");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o2) {
System.out.println(Thread.currentThread().getName()+"得到资源o2");
}
}
}else{
flag = true;
synchronized (o2) {
System.out.println(Thread.currentThread().getName()+"锁住资源o2,等到o1");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o1) {
System.out.println(Thread.currentThread().getName()+"得到资源o1");
}
}
}
}
}
真正的做法是这样子的
public class DeadLockDemo {
private static Object resource1 = new Object();
private static Object resource2 = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource2");
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
}
}
}, "线程 1").start();
new Thread(() -> {
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource1");
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
}
}
}, "线程 2").start();
}
}
内部类的形式
public class DeadLock {
private static ReentrantLock lockA = new ReentrantLock();
private static ReentrantLock lockB = new ReentrantLock();
public static void main(String[] args) {
new Thread(new A()).start();
new Thread(new B()).start();
}
static class A implements Runnable{
@Override
public void run() {
Thread.currentThread().setName("A线程");
lockA.lock();
System.out.println(Thread.currentThread().getName()+"获取锁A");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lockB.lock();
System.out.println(Thread.currentThread().getName()+"获取锁B");
lockA.unlock();
lockB.unlock();
}
}
static class B implements Runnable{
@Override
public void run() {
Thread.currentThread().setName("B线程");
lockB.lock();
System.out.println(Thread.currentThread().getName()+"获取锁B");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lockA.lock();
System.out.println(Thread.currentThread().getName()+"获取锁A");
}
}
}