老规矩,先看例子
public class DeadLock {
public static void main(String[] args) {
Runnable r1 = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized ("A") {
System.out.println("A线程持有了A锁,等待B锁");
synchronized ("B") {
System.out.println("A线程持有了A锁和B锁");
}
}
}
};
Runnable r2 = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized ("B") {
System.out.println("B线程持有了B锁,等待A锁");
synchronized ("A") {
System.out.println("B线程持有了A锁和B锁");
}
}
}
};
Thread threadA = new Thread(r1);
Thread threadB = new Thread(r2);
threadA.start();
threadB.start();
}
}
我们发现程序没有停止,因为threadA一直在等待B锁,B锁却被threadB抢走了,这时候threadA还没有执行完并不释放A锁,同理threadB在等待A锁,两个人就这样一直等下去,形成了死锁。
死锁:多个线程互相持有对方需要的锁对象,而不释放自己的锁。
解决
public class DeadLock {
//wait()等待,是Object中的方法,当前线程释放自己的所标记,让出CPU资源,使当前线程进入等待队列
//notify()通知,是Object中的方法,唤醒等待队列中的一个线程,使这个线程进入锁池。
//notifyAll()通知,唤醒等待队列中的所有线程,并使这些线程进入锁池。
public static void main(String[] args) {
Runnable r1 = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized ("A") {
System.out.println("A线程持有了A锁,等待B锁");
try {
"A".wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized ("B") {
System.out.println("A线程持有了A锁和B锁");
}
}
}
};
Runnable r2 = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized ("B") {
System.out.println("B线程持有了B锁,等待A锁");
synchronized ("A") {
System.out.println("B线程持有了A锁和B锁");
//唤醒所有等待A锁的线程
"A".notifyAll();
}
}
}
};
Thread threadA = new Thread(r1);
Thread threadB = new Thread(r2);
threadA.start();
threadB.start();
}
}
wait()等待,是Object中的方法,当前线程释放自己的所标记,让出CPU资源,使当前线程进入等待队列
notify()通知,是Object中的方法,唤醒等待队列中的一个线程,使这个线程进入锁池。
notifyAll()通知,唤醒等待队列中的所有线程,并使这些线程进入锁池。