关于多线程的一些知识点(三)——死锁

老规矩,先看例子

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();
    }
}
image.png

我们发现程序没有停止,因为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()通知,唤醒等待队列中的所有线程,并使这些线程进入锁池。

你可能感兴趣的:(关于多线程的一些知识点(三)——死锁)