一,死锁是什么
死锁是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。
相当于两台并行前进的车,左边的车想变道右边,右边的车想变道左边,谁也不让谁。
死锁代码:
public class DeadLock {
public static class MyThread implements Runnable {
Object obj = new Object();
public void run() {
System.out.println( Thread.currentThread().getName() + "run prepare");
synchronized(obj) {// obj锁
System.out.println( Thread.currentThread().getName() + "run start");
doSomething(); // this锁
}
}
public void doSomething() { // this锁
System.out.println( Thread.currentThread().getName() + "doSomething start");
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(obj) { // obj锁
System.out.println( Thread.currentThread().getName() + "doSomething synchronized");
}
}
}
public static void main(String[] args) {
MyThread t = new MyThread();
Thread th = new Thread(t);
Thread th2 = new Thread(t);
th.start();
th2.start();
}
}
结果:
.jar:/Users/lucy6/Documents/maven/Spring2/out/production/lock DeadLock
Thread-1run prepare
Thread-0run prepare
Thread-1run start
Thread-1doSomething start
Thread-1doSomething synchronized
Thread-0run start
Thread-0doSomething start
Thread-0doSomething synchronized
Process finished with exit code 0
分析:
线程1首先执行,打印Thread-1run prepare
线程0马上抢到执行权,打印Thread-0run prepare
线程1有抢到执行权,进入同步代码块,拿到obj锁,打印:
Thread-1doSomething start、
Thread-1doSomething start、
Thread-1doSomething synchronized
然后线程进入冻结状态,相当于放弃cpu执行权。
显然线程0会拿到cpu执行权,接下来线程0应该进入同步代码块,但是什么都没有发生,因为obj被线程1拿着没释放,出现死锁。
当线程1冻结时间到,重新拿回cpu执行权,执行完所有代码,释放锁,然后线程0得以继续执行。
二,一个更好的例子
public class DeadLock2 {
static Object objA = new Object();
static Object objB = new Object();
public static class MyThread implements Runnable {
public void run() {
System.out.println(Thread.currentThread().getName() + ",run prepare");
synchronized (objA) {// obj锁
System.out.println(Thread.currentThread().getName() + ",拿到objA锁");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (objB) {
System.out.println(Thread.currentThread().getName() + ",拿到objA锁");
}
}
}
}
public static class MyThread2 implements Runnable {
public void run() {
System.out.println(Thread.currentThread().getName() + "run prepare");
synchronized (objB) {// obj锁
System.out.println(Thread.currentThread().getName() + ",拿到 objB锁");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (objA) {
System.out.println(Thread.currentThread().getName() + ",拿到 objA锁");
}
}
}
}
public static void main(String[] args) {
MyThread t = new MyThread();
MyThread2 t2 = new MyThread2();
Thread th = new Thread(t);
Thread th2 = new Thread(t2);
th.start();
th2.start();
}
}
三,死锁产生的条件
1,多线程
2,多个锁
3,锁嵌套