JUC Concurrency Series (3): Concurrency in interviews, and I get confused when I ask (An article on the angry liver thoroughly understands the lock, and the interview is not panic)

It is not difficult to run a program; the difficult thing is how far the program can run! —— a fierce seed

Insert picture description here
JUC Concurrency Series

JUC Concurrency Series (1): What? I heard that you confuse concurrency and parallel
JUC concurrency series (2): Detailed Condition to achieve accurate notification wakeup

The existence of the lock core is multi-threaded and concurrent, only a thorough understanding of locks, encounter interview do not panic, but also to deal with concurrency issues in practical work with the salary lock to be arbitrary.
Insert picture description here

1. Who decides the execution order of multiple synchronization methods

Under normal circumstances, the execution order of the two threads is not executed sequentially (from top to bottom), but the existence of a lock. After the same lock is used, they are executed in sequence.

The lock here is the lock of the same object, the lock of the computer object, so whoever is first will execute it first.

Computer computer = new Computer();

1.1 Hand type code implementation

Here we have written two methods (locked two methods, that is, synchronization method), one is learning, the other is playing games.

public class Demo{
    
    
    public static void main(String[] args) {
    
    
        Computer computer = new Computer();

        new Thread(()->{
    
    
            computer.study();
        },"a").start();

        try {
    
    
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }

        new Thread(()->{
    
    
            computer.game();
        },"b").start();
    }
}
class Computer{
    
    

    public synchronized void study(){
    
    
        try {
    
    
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("学习");
    }
    public synchronized void game(){
    
    
        System.out.println("打游戏");
    }
}

operation result

You can see who is in front and who will execute first, so the order is also learn first, then play.

Insert picture description here

Second, the synchronization method in multiple objects

The execution order of synchronization methods for multiple object locks is still the same, but unlike an object lock, multiple object locks will affect the execution order due to sleep time.

2.1 Hand-knock code implementation

In the above code, we only lock one object, then add another object lock, two objects, and the same two methods. Would you answer that you learn first and then play?

public class Demo{
    
    
    public static void main(String[] args) {
    
    
        Computer computer1 = new Computer();
        Computer computer2 = new Computer();

        new Thread(()->{
    
    
            computer1.study();
        },"a").start();

        try {
    
    
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }

        new Thread(()->{
    
    
            computer2.game();
        },"b").start();


    }
}
class Computer{
    
    

    public synchronized void study(){
    
    
        try {
    
    
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("学习");
    }
    public synchronized void game(){
    
    
        System.out.println("打游戏");
    }
}

operation result

The correct answer is: play the game first, then learn.

Insert picture description here

Three. Synchronous and non-synchronous methods

The difference between the synchronous method and the asynchronous method is that the asynchronous method is not affected by the lock.

3.1 Hand-made code implementation

In the code of 1.1 above, we have added an asynchronous method (ordinary method) for watching movies. We can verify the order of execution.

 public void movie(){
    
    
        System.out.println("看电影");
    }
public class Demo{
    
    
    public static void main(String[] args) {
    
    
        Computer computer = new Computer();

        new Thread(()->{
    
    
            computer.study();
        },"a").start();

        try {
    
    
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }

        new Thread(()->{
    
    
            computer.game();
        },"b").start();

        new Thread(()->{
    
    
            computer.movie();
        },"c").start();
    }
}
class Computer{
    
    

    public synchronized void study(){
    
    
        try {
    
    
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("学习");
    }
    public synchronized void game(){
    
    
        System.out.println("打游戏");
    }

    public void movie(){
    
    
        System.out.println("看电影");
    }
}

operation result
Insert picture description here

Four, static synchronization method

In the previous article, we talked about the internal classes of Java in a simple way. We talked about static being the first to be executed, and it will be automatically called when the bytecode is loaded, and before the main method main, it is earlier than the construction method. At this time, non-static properties and methods are not yet available. Complete the initialization.

Ultra-detailed in-depth understanding of Java internal classes

The static method is available as soon as the class is loaded, so the locked class itself is the same object.

4.1 Hand-type code implementation

We still create two object locks, but the difference is that our methods have added static to become static methods, let's see the order of execution.

public class Demo{
    
    
    public static void main(String[] args) {
    
    
        Computer computer = new Computer();

        new Thread(()->{
    
    
            computer.study();
        },"a").start();

        try {
    
    
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }

        new Thread(()->{
    
    
            computer.game();
        },"b").start();
    }
}
class Computer{
    
    

    public static synchronized void study(){
    
    
        try {
    
    
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("学习");
    }
    public static synchronized void game(){
    
    
        System.out.println("打游戏");
    }
}

operation result

Insert picture description here

5. Comparison of static synchronization method and ordinary synchronization method

If you understand the above static synchronization method, I believe you also understand the difference between static synchronization method and ordinary synchronization method.

The static static synchronization method locks the class class, while the normal synchronization method locks the call, so they are two different locks.

After understanding this passage, you also understand the code and the output result.

5.1 Hand code implementation

The following code also creates an object, or two methods, the difference is that the output learning is a static synchronization method, while the output playing game is a normal method, if you can understand

public class Demo{
    
    
    public static void main(String[] args) {
    
    
        Computer computer = new Computer();
        new Thread(()->{
    
    
            computer.study();
        },"a").start();

        try {
    
    
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }

        new Thread(()->{
    
    
            computer.game();
        },"b").start();
    }
}
class Computer{
    
    

    public static synchronized void study(){
    
    
        try {
    
    
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("学习");
    }
    public synchronized void game(){
    
    
        System.out.println("打游戏");
    }
}

operation result

You can see that the static synchronization method and the ordinary synchronization method are two different locks. If there is no sleep, the static synchronization method is executed first, because it is called when the class is loaded (important things, countless times), but However, in the case of sleep delay, our ordinary method is executed first because of the delay;
Insert picture description here
remember that the static synchronization method and the ordinary method are not the same lock, the former is the class, and the latter is the caller.

Six, finally

At the end, for a better reading experience, I put everything I want to say below, hehe.

I am a seed of decisions based on my will, serious share what I wrote blog has been the same creed.
If you can read this blog post, it means that we are still very destined; I hope it can bring you some help, the creation is not easy,
take away the knowledge of my article, your three consecutive leave, like, comment, follow , Is my biggest motivation.

Guess you like

Origin blog.csdn.net/A_hxy/article/details/108680962