面试被问到,Java如何避免死锁?引发的思考。

模拟死锁:

/**
 * Create by LiXiaoTian 2020/5/10 11:34
 * 死锁问题
 */
public class Deadlock {

    public static String resource1 = "resource1";
    public static String resource2 = "resource2";
    public static void main(String[] args) {
        Thread thread1 = new Thread(new BusinessA());
        Thread thread2 = new Thread(new BusinessB());
        thread1.setName("线程1");
        thread2.setName("线程2");
        thread1.start();
        thread2.start();
    }
    static class BusinessA implements Runnable {
        @Override
        public void run() {
            try{
                System.out.println("BusinessA启动");
                while(true){
                    synchronized(Deadlock.resource1){
                        System.out.println("BusinessA拿到了resource1的锁");
                        Thread.sleep(3000);//获取resource1后先等一会儿,让BusinessB有足够的时间锁住resource2
                        System.out.println("BusinessA想拿resource2的锁。。。。");
                        synchronized(Deadlock.resource2){
                            System.out.println("BusinessA获得到了resource2的锁");
                        }
                    }
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
    static class BusinessB implements Runnable {
        @Override
        public void run(){
            try{
                System.out.println("BusinessB启动");
                while(true){
                    synchronized(Deadlock.resource2){
                        System.out.println("BusinessB拿得到了resource2的锁");
                        Thread.sleep(3000);//获取resource2后先等一会儿,让BusinessA有足够的时间锁住resource1
                        System.out.println("BusinessB想拿resource1的锁。。。。");
                        synchronized(Deadlock.resource1){
                            System.out.println("BusinessB获得到了resource1的锁");
                        }
                    }
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }

}

面试被问到,Java如何避免死锁?引发的思考。_第1张图片

面试被问到,Java如何避免死锁?引发的思考。_第2张图片 

面试被问到,Java如何避免死锁?引发的思考。_第3张图片 

如何解决死锁呢?

解决方法:

1、线程因某个条件为未满足而受阻,不能让其继续占有资源,也就是说,让进入阻塞状态的线程释放所有资源。

2、如果有多个对象需要互斥访问,应该确定线程获得锁的顺序,并保证整个程序以相反的顺序释放锁。也就是说,一个线程获得一个资源的锁之后,不能再占用其他对象资源的锁,释放资源锁的顺序:先被占有的资源的锁后释放。

/**
 * Create by LiXiaoTian 2020/5/10 11:34
 * 解决死锁问题
 */
public class Deadlock {

    public static ReentrantLock lock1 = new ReentrantLock();
    public static ReentrantLock lock2 = new ReentrantLock();

    public static String resource1 = "resource1";
    public static String resource2 = "resource2";

    public static void main(String[] args) {
        Thread thread1 = new Thread(new BusinessA());
        Thread thread2 = new Thread(new BusinessB());
        thread1.setName("线程1");
        thread2.setName("线程2");
        thread1.start();
        thread2.start();
    }

    static class BusinessA implements Runnable {
        boolean flag = true;

        @Override
        public void run() {
            try {
                System.out.println("线程1启动");
                while (flag) {
                    Thread.sleep(1000);
                    if (Deadlock.lock1.tryLock(1, TimeUnit.SECONDS)) {
                        System.out.println("线程1已锁住lock1");
                        Thread.sleep(5000);
                        if (Deadlock.lock2.tryLock(1, TimeUnit.SECONDS)) {
                            System.out.println("线程1已锁住lock2");
                            flag = false;
                        } else {
                            System.out.println("线程1锁失败lock2");
                        }
                    } else {
                        System.out.println("线程1锁失败lock1");
                    }
                    System.out.println("当前线程===========================" + Thread.currentThread().getName());
                    //释放锁
                    if (lock1.isHeldByCurrentThread()) {
                        lock1.unlock();
                        System.out.println("线程1释放lock1");
                    }
                    if (lock2.isHeldByCurrentThread()) {
                        lock2.unlock();
                        System.out.println("线程1释放lock2");
                    }
                    Thread.sleep(2000);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    static class BusinessB implements Runnable {

        boolean flag = true;

        @Override
        public void run() {
            try {
                System.out.println("线程2启动");
                while (flag) {
                    if (Deadlock.lock1.tryLock(1, TimeUnit.SECONDS)) {
                        System.out.println("线程2已锁住lock1");
                        Thread.sleep(6000);
                        if (Deadlock.lock2.tryLock(1, TimeUnit.SECONDS)) {
                            System.out.println("线程2已锁住lock2");
                            flag = false;
                        } else {
                            System.out.println("线程2锁失败lock2");
                        }
                    } else {
                        System.out.println("线程2锁失败lock1");
                    }
                    System.out.println("当前线程===========================" + Thread.currentThread().getName());
                    //释放锁
                    if (lock1.isHeldByCurrentThread()) {
                        lock1.unlock();
                        System.out.println("线程2释放lock1");
                    }
                    if (lock2.isHeldByCurrentThread()) {
                        lock2.unlock();
                        System.out.println("线程2释放lock2");
                    }

                }
                Thread.sleep(2000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

 

 

你可能感兴趣的:(并发编程系列)