Java deadlock code demo (the most popular understanding in history)

Java deadlock code demo

The concept of deadlock

Knowledge reserve


Object lock : Everything in Java is an object, and each class has a class file. Objects can be new from the class file. We simply understand the java object. The object has an object header information, which is the overview of the object. One piece of information is the object lock, that is, whether our current object is locked and which reference is locked.


synchronized : synchronized is a java keyword. If it is applied to a method, it means that we lock this method. If we lock a code block, it means that we hold this lock in this code block. Java Effective also advocates reducing the scope of the lock. When we enter the synchronized code block, the lock will be added, and the lock will be released after the synchronized code block is executed.


Deadlock : popularly understood as a dead lock. If there is no dead lock, its life cycle is: hold lock -> release lock. After death, we can understand it as holding the lock but not releasing the lock, that is, our synchronization code block has not been executed? We only need to analyze where the synchronization code block is not executed, look at the following example


Demo deadlock

package com.yang.kuangTeacher;

import java.util.concurrent.TimeUnit;

/**
 * @author: fudy
 * @date: 2020/9/13 下午 12:21
 * @Decription: 演示死锁(内容参考B站狂神说JAVA)
 **/
public class DeadLock {
    
    

    public static void main(String[] args) {
    
    
        MarkUp markUp0 = new MarkUp("迪丽热巴",0);
        MarkUp markUp1 = new MarkUp("杨幂",1);
        markUp0.start();
        markUp1.start();
    }
}

// 口红类
class LipStick {
    
    
}

// 镜子类
class Mirror {
    
    
}

// 化妆类
class MarkUp extends Thread {
    
    

    private int choice;
    private String userName;

    private static LipStick lipStick = new LipStick();
    private static Mirror mirror = new Mirror();

    MarkUp(String userName, int choice) {
    
    
        this.userName = userName;
        this.choice = choice;
    }

    @Override
    public void run() {
    
    
        try {
    
    
            markUP();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
    }

    private void markUP() throws InterruptedException {
    
    
        // 如果选择0方式化妆
        if (choice == 0) {
    
    
            // 同步代码块的锁,在同步代码块有效
            synchronized (lipStick) {
    
    
                System.out.println(userName + "拿到了口红");
                // 拿到口红后再拿镜子
                TimeUnit.SECONDS.sleep(1);
                // 程序执行此处会停止 		 -----------------这里死锁----------------------->
                synchronized (mirror) {
    
    
                    System.out.println(userName + "拿到了镜子");
                }
            }
        }
        // 如果选择1方式化妆
        if (choice == 1) {
    
    
            // 同步代码块的锁,在同步代码块有效
            synchronized (mirror) {
    
    
                System.out.println(userName + "拿到了镜子");
                // 拿到镜子后再拿口红
                TimeUnit.SECONDS.sleep(1);
                // 程序执行此处会停止          -----------------这里死锁----------------------->
                synchronized (lipStick) {
    
    
                    System.out.println(userName + "拿到了口红");
                }
            }
        }
    }
}

We just thought that the deadlock is due to the incomplete execution of the synchronization code block, and the lock will not be released. We analyze the causes of the above two deadlocks.


  • In thread 1 mode 0 makeup, because we got the lipstick lock, sleep for one second (it is possible to execute thread 2 first)

  • In thread 2 way 1 makeup, because we got the mirror lock, sleep for one second


If thread 1 first obtains the lipstick lock and finishes execution, when preparing to take the mirror lock, it finds that the mirror object is held, so it will wait for the mirror lock to be released.

Thread 2 executes first to obtain the mirror lock, and when preparing to take the lipstick lock, it is found that the lipstick object is held, so he will wait for the lipstick lock to be released.

If we do not close the program, the two threads will wait forever. We can understand it as a deadlock and cannot release the lock.


Resolve deadlock

In the above example, we want to get two locks to do one thing at the same time will lead to deadlock, according to Java Effective advocates to reduce the scope of the lock, we improve the problem.

We can get the lipstick lock and execute the lipstick method and then release the lipstick lock. If we want the mirror lock, we can synchronize the code block to get the mirror lock.

package com.yang.kuangTeacher;

import java.util.concurrent.TimeUnit;

/**
 * @author: fudy
 * @date: 2020/9/13 下午 12:21
 * @Decription: 演示死锁(内容参考B站狂神说JAVA)
 **/
public class DeadLock {
    
    

    public static void main(String[] args) {
    
    
        MarkUp markUp0 = new MarkUp("迪丽热巴",0);
        MarkUp markUp1 = new MarkUp("杨幂",1);
        markUp0.start();
        markUp1.start();
    }
}

// 口红类
class LipStick {
    
    
}

// 镜子类
class Mirror {
    
    
}

// 化妆类
class MarkUp extends Thread {
    
    

    private int choice;
    private String userName;

    private static LipStick lipStick = new LipStick();
    private static Mirror mirror = new Mirror();

    MarkUp(String userName, int choice) {
    
    
        this.userName = userName;
        this.choice = choice;
    }

    @Override
    public void run() {
    
    
        try {
    
    
            markUP();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
    }

    private void markUP() throws InterruptedException {
    
    
        // 如果选择0方式化妆
        if (choice == 0) {
    
    
            // 同步代码块的锁,在同步代码块有效
            synchronized (lipStick) {
    
    
                System.out.println(userName + "拿到了口红");
                TimeUnit.SECONDS.sleep(1);
            }
            // 拿到口红后再拿镜子           ------------------------改进---------------------------
            synchronized (mirror) {
    
    
                System.out.println(userName + "拿到了镜子");
            }
        }
        // 如果选择1方式化妆
        if (choice == 1) {
    
    
            // 同步代码块的锁,在同步代码块有效
            synchronized (mirror) {
    
    
                System.out.println(userName + "拿到了镜子");
                TimeUnit.SECONDS.sleep(1);
            }
            // 拿到镜子后再拿口红            ------------------------改进---------------------------
            synchronized (lipStick) {
    
    
                System.out.println(userName + "拿到了口红");
            }
        }
    }
}

​ By releasing the lock in time, that is, reducing the scope of the synchronization code block, we release it in time after the end of the lock. This is a way to solve the deadlock. Through this example, we will be alert to the scope of the synchronization code of the lock in the future.

Guess you like

Origin blog.csdn.net/qq_44112474/article/details/108561452