Java Concurrency 03---Deadlock of Thread Technology



  We know that using the synchronized keyword can effectively solve the problem of thread synchronization, but if the synchronized keyword is used inappropriately, there will be problems, which is what we call deadlock. A deadlock is a situation where multiple threads are blocked at the same time, and one or all of them are waiting for a resource to be released. Since the thread is blocked indefinitely, it is impossible for the program to terminate normally.
  Write an example of a deadlock below to deepen your understanding. First look at the program, and then analyze the cause of the deadlock:

public class DeadLock {

    public static void main(String[] args) {
        Business business = new Business1();
        //开启一个线程执行Business类中的functionA方法
        new Thread(new Runnable() {

            @Override
            public void run() {
                while(true) {
                    business.functionA();
                }
            }
        }).start();

        //开启另一个线程执行Business类中的functionB方法
        new Thread(new Runnable() {

            @Override
            public void run() {
                while(true) {
                    business.functionB();
                }
            }
        }).start();
    }

}

class Business { //定义两个锁,两个方法
    //定义两个锁
    public static final Object lock_a = new Object();
    public static final Object lock_b = new Object();   

    public void functionA() {
        synchronized(lock_a) {
            System.out.println("---ThreadA---lock_a---");
            synchronized(lock_b) {
                System.out.println("---ThreadA---lock_b---");
            }
        }
    }

    public void functionB() {
        synchronized(lock_b) {
            System.out.println("---ThreadB---lock_b---");
            synchronized(lock_a) {
                System.out.println("---ThreadB---lock_a---");
            }
        }
    }
}
  
  

      The program structure is very clear and there is no difficulty. Let's first look at the execution results of the program:

    —ThreadA—lock_a—
    —ThreadA—lock_b—
    —ThreadA—lock_a—
    —ThreadA—lock_b—
    —ThreadA—lock_a—
    —ThreadA—lock_b—
    —ThreadA—lock_a—
    —ThreadB—lock_b—

      Judging from the execution results, thread A runs and runs, and when thread B runs, it hangs with a snap~ Let's analyze the reason: As can be seen from the above code, a class Business is defined, in which Two locks and two methods are maintained, each of which is synchronized and uses a different lock. Well, now two threads A and B are opened in the main method to execute the two methods in the Business class respectively. A is executed first, and it runs very well. When thread B also starts to execute, the problem comes. From the last two lines of the execution result, thread A enters the first synchronized in the functionA method and gets the lock_a lock. Thread B entered the first synchronized in functionB, got the lock_b lock, and the locks of both have not been released. The next step is the key: when thread A enters the second synchronized, it finds that lock_b is being occupied by B, then there is no way, it has to be blocked, wait ~ Similarly, when thread B enters the second synchronized, it finds lock_a It is being occupied by A, then there is no other way, it has to be blocked, wait~ Okay, the two are waiting for each other like this, you don't let me, I won't let go... Dead...
      The above program is useful for understanding deadlocks Very helpful, because the structure is very good, but I personally feel that this is not enough to die, because the two threads implement two different Runnable interfaces, but only call two methods of the same class, because I want to Synchronized methods are placed in a class. Next, I will change the program, put the code to be synchronized into a Runnable, and let it hang as soon as it runs...

    public class DeadLock { 
    
        public static void main(String[] args) {        
    
            //开启两个线程,分别扔两个自定义的Runnable进去
            new Thread(new MyRunnable(true)).start();;
            new Thread(new MyRunnable(false)).start();;
    
        }
    }
    
    class MyRunnable implements Runnable
    {
        private boolean flag; //用于判断,执行不同的同步代码块
    
        MyRunnable(boolean flag) { //构造方法
            this.flag = flag;
        }
    
        @Override
        public void run()
        {
            if(flag)
            {
                while(true){            
                    synchronized(MyLock.lock_a)
                    {
                        System.out.println("--threadA---lock_a--");
                        synchronized(MyLock.lock_b)
                        {
                            System.out.println("--threadA---lock_b--");
                        }   
                    }
                }
            }
            else
            {
                while(true){            
                    synchronized(MyLock.lock_b)
                    {
                        System.out.println("--threadB---lock_a--");
                        synchronized(MyLock.lock_a)
                        {
                            System.out.println("--threadB---lock_b--");
                        }   
                    }
                }
            }
        }
    }
    
    class MyLock //把两把锁放到一个类中定义,是为了两个线程使用的都是这两把锁
    {
        public static final Object lock_a = new Object();
        public static final Object lock_b = new Object();   
    }
      
      

        This deadlock is very powerful. As soon as it runs, it hangs up with a click... Look at the running result:

      –threadA—lock_a–
      –threadB—lock_b–

        The above are two examples of deadlocks, both of which are easier to understand and remember. The main reason is that the "design patterns" are not the same. The first structure is clearer. You only need to run the logic in the main function, and the synchronization part is all thrown to the Business , this is convenient for post-maintenance, I can just throw the Business anywhere to execute it, because all the synchronized things are in its own class, this design idea is very good. The second is to define the Runnable first, and pass in different boolean type values ​​through the construction method to decide to execute different parts of the run() method. This idea is also easy to understand. This kind of deadlock is more severe, and the two threads directly Execute the opposite part, hang up directly, and don't show any affection to the other party~
        
        Related reading: http://blog.csdn.net/column/details/bingfa.html




        We know that using the synchronized keyword can effectively solve the problem of thread synchronization, but if the synchronized keyword is used inappropriately, there will be problems, which is what we call deadlock. A deadlock is a situation where multiple threads are blocked at the same time, and one or all of them are waiting for a resource to be released. Since the thread is blocked indefinitely, it is impossible for the program to terminate normally.
        Write an example of a deadlock below to deepen your understanding. First look at the program, and then analyze the cause of the deadlock:

      Guess you like

      Origin http://10.200.1.11:23101/article/api/json?id=326945947&siteId=291194637