Interviewer: Can synchronized prohibit instruction reordering?

1. Instruction reordering

     1. Problem description

     2. DCL code bytecode analysis instruction reordering problem

2. Orderliness

     1. Code example

instruction reordering

1. Problem description

First of all, it must be clear: instruction reordering and ordering are not the same.

We often say:

  • Volatile can guarantee memory visibility and prohibit instruction reordering, but cannot guarantee atomicity.

  • Synchronized can guarantee atomicity, visibility and order.

Note: The order here does not mean that instruction reordering can be prohibited.

for example:

In the double-checked singleton mode, why do you need volatile to modify variables after synchronized has been added? If synchronized can prohibit instruction rearrangement, then volatile is completely unnecessary.

2. DCL code bytecode analysis instruction reordering problem

First of all, you need to know: Object obj = new Object(); This code is not an atomic operation, but is divided into three steps:

  • Apply for a space in memory, and create an object with new

  • Call the constructor of this object from new

  • Assign a reference to this object to obj

(1) DCL double check code

public class MySingleton {
    private static MySingleton INSTANCE;
    private MySingleton() {
    }
    public static MySingleton getInstance() {
        if (INSTANCE == null) {
            synchronized (MySingleton.class) {
                if (INSTANCE == null) {
                    INSTANCE = new MySingleton();
                }
            }
        }
        return INSTANCE;
    }
}

(2) The bytecode is as follows

picture

As can be seen from the bytecode, new MySingleton(); This line of code corresponds to the four lines of bytecode 17, 20, 21, and 24 (line 20 is a reference copy, which can be ignored).

  • First create a MySingleton object by opening up a space in memory on line 17.

  • Then call the object's constructor on line 21.

  • Then assign the reference of the object to the static variable INSTANCE on line 24.

The above is the execution order we expect, and we hope that each thread executes instructions in this order (this is to prohibit instruction reordering). However, in order to improve operating efficiency, the computer will optimize the order of our instructions (for example, the above order may be optimized and rearranged as: 17, 24, 21).

Problems with instruction reordering

  • For example, the execution order in the t1 thread is 17, 24, 21, and the execution order in the t2 thread is 17, 21, 24 (no matter which execution order is in a single thread, there will be no problem).

  • When the t1 thread acquires the lock and executes object creation, it executes line 24 first, and assigns the reference of the object to the static variable INSTANCE (at this time, the object has not yet called the constructor, and the object is not yet a complete object).

  • At this time, the t2 thread starts to run. When the t2 thread executes the if (INSTANCE == null) (line 16 code) statement, the t2 thread finds that INSTANCE is not empty. At this time, the t2 thread directly returns the INSTANCE object. But at this time, the object is still an incomplete object, and problems will occur when the t2 thread uses the object.

So there is no problem with instruction reordering in a single thread, but once it involves multi-threading, instruction reordering may bring unexpected results.

orderliness

Since synchronized cannot prohibit the reordering of instructions, what order is the order it guarantees?

Its essence is to allow multiple threads to change from parallel (concurrent) to serial calls when calling synchronized modified methods, and whoever acquires the lock will execute.

1. Code example

Both threads t1 and t2 need to obtain the singleton object, and then call the test method, and the test method is a method with a synchronization lock.

public class MySingleton {
    private static MySingleton INSTANCE;
    private MySingleton() {
    }
    public static MySingleton getInstance() {
        if (INSTANCE == null) {
            synchronized (MySingleton.class) {
                if (INSTANCE == null) {
                    INSTANCE = new MySingleton();
                }
            }
        }
        return INSTANCE;
    }
    public static void test(final MySingleton singleton) {
        synchronized (MySingleton.class) {
            System.out.println(singleton);
        }
    }
}

2. Test code

public class MySingletonTest {
  // 可以看到两个线程都需要去获取单例对象,然后调用test方法,并且test方法是加了同步锁的方法
    public static void main(final String[] args) {
        new Thread(() -> {
            MySingleton instance = MySingleton.getInstance();
            MySingleton.test(instance);
        }, "t1").start();
        new Thread(() -> {
            MySingleton instance = MySingleton.getInstance();
            MySingleton.test(instance);
        }, "t2").start();
    }
}

Even if the t2 thread obtains the object that has not called the constructor, then there will be no problem when calling the MySingleton.test(instance); method in the t2 thread. Because of the use of synchronization locks, each one-lock execution method becomes serial, and concurrent execution becomes serial. When the t2 thread acquires the lock and executes it, t1 has already released the lock. At this time The instance has already been instantiated already. So there will be no problem.

So synchronized guarantees sequentiality refers to turning concurrent execution into serial, but it does not guarantee the reordering of internal instructions.

Finally: The complete software testing video tutorial below has been sorted out and uploaded, and friends who need it can get it by themselves [Guaranteed 100% free]

Software Testing Interview Documentation

We must study to find a high-paying job. The following interview questions are the latest interview materials from first-tier Internet companies such as Ali, Tencent, and Byte, and some Byte bosses have given authoritative answers. Finish this set The interview materials believe that everyone can find a satisfactory job.

Guess you like

Origin blog.csdn.net/wx17343624830/article/details/132501682