如何构建一个死锁?

程序中的死锁指的是两个或两个以上的线程,相互等待对方释放某个锁,而造成无限等待的一种情况

如何构建死锁?

以下就是一个死锁的例子

package MultiThread;

/** 
 * Java program to create a deadlock by imposing circular wait.
 * 
 * @author William
 * 
 */

public class DeadLock {


    private class Running1 implements Runnable {
        /*
         * This method request two locks, first String and then Integer
         */
        @Override
        public void run() {
            while (true) {
                synchronized (String.class) {
                    System.out.println("Thread1 Aquired lock on String.class object");

                    synchronized (Integer.class) {
                        System.out.println("Thread1 Aquired lock on Integer.class object");
                    }
                }               
            }
        }

    }

    private class Running2 implements Runnable {
        /*
         * This method also requests same two lock but in exactly
         * Opposite order i.e. first Integer and then String
         * This creates potential deadlock, if one thread holds String lock
         * and other holds Integer lock and they wait for each other, forever
         */
        @Override
        public void run() {
            while (true) {
                synchronized (Integer.class) {
                    System.out.println("Thread2 Aquired lock on Integer.class object");

                    synchronized (String.class) {
                        System.out.println("Thread2 Aquired lock on String.class object");
                    }
                }               
            }
        }       
    }

    public static void main(String[] args) {
        DeadLock deadLock = new DeadLock();
        Running1 r1 = deadLock.new Running1();
        Running2 r2 = deadLock.new Running2();

        Thread thread1 = new Thread(r1);
        Thread thread2 = new Thread(r2);

        thread1.start();
        thread2.start();
    }
}
Console output :

Thread1 Aquired lock on String.class object
Thread2 Aquired lock on Integer.class object
无限等待

在上面这个例子中,我们有两个线程,以相反的顺序去获取两个锁,最后陷入了Thread1持有String锁,等待Integer锁,Thread2持有Integer锁,等待String锁的无限等待,即死锁情景

如何避免死锁?

避免死锁的关键在于应使不同线程获取锁的顺序保持一致,例如都先获取String锁,再获取Integer锁,我们可以做如下修改

package MultiThread;

/** 
 * Java program to create a deadlock by imposing circular wait.
 * 
 * @author William
 * 
 */

public class DeadLock {


    private class Running1 implements Runnable {
        /*
         * This method request two locks, first String and then Integer
         */
        @Override
        public void run() {
            while (true) {
                synchronized (String.class) {
                    System.out.println("Thread1 Aquired lock on String.class object");

                    synchronized (Integer.class) {
                        System.out.println("Thread1 Aquired lock on Integer.class object");
                    }
                }               
            }
        }

    }

    private class Running2 implements Runnable {
        /*
         * This method requests same two lock in the same
         * order i.e. first String and then Integer
         * This will not create any deadlock risk 
         */
        @Override
        public void run() {
            while (true) {
                synchronized (String.class) {
                    System.out.println("Thread2 Aquired lock on Integer.class object");

                    synchronized (Integer.class) {
                        System.out.println("Thread2 Aquired lock on String.class object");
                    }
                }               
            }
        }       
    }

    public static void main(String[] args) {
        DeadLock deadLock = new DeadLock();
        Running1 r1 = deadLock.new Running1();
        Running2 r2 = deadLock.new Running2();

        Thread thread1 = new Thread(r1);
        Thread thread2 = new Thread(r2);

        thread1.start();
        thread2.start();
    }
}
Console output :

Thread1 Aquired lock on String.class object
Thread1 Aquired lock on Integer.class object
Thread1 Aquired lock on String.class object
Thread1 Aquired lock on Integer.class object
Thread2 Aquired lock on String.class object
Thread2 Aquired lock on Integer.class object
...

你可能感兴趣的:(不那么基础的Java基础)