Why does the volatile keyword need to be added to Java singleton mode?
Foreword:
There are many ways to implement singleton mode, such as hungry mode, lazy mode, static inner class and enumerations, etc., when the interviewer asks "Why must volatile be added to the singleton mode?", then he is referring to why the private variables in the lazy mode must be added volatile?
Lazy mode refers to the lazy loading method of object creation. The object is not created when the program starts, but is created only when it is actually used for the first time.
Would you like to explain why you need to add volatile? Let’s first look at the specific implementation code of lazy mode:
public class Singleton { // 1.防止外部直接 new 对象破坏单例模式 private Singleton() {} // 2.通过私有变量保存单例对象【添加了 volatile 修饰】 private static volatile Singleton instance = null; // 3.提供公共获取单例对象的方法 public static Singleton getInstance() { if (instance == null) { // 第 1 次效验 synchronized (Singleton.class) { if (instance == null) { // 第 2 次效验 instance = new Singleton(); } } } return instance; } }
As can be seen from the above code, in order to ensure thread safety and high performance, if and synchronized are used twice in the code to ensure the execution of the program. . So since there is already synchronized to ensure thread safety, why do we need to add volatile to the variable? Before explaining this problem, we must first understand a prerequisite knowledge: What is the use of volatile?
1. Volatile function
volatile has two main functions. First, it solves the problem of memory visibility. Second, it prevents instruction reordering.
1.1 Memory visibility problem
The so-called memory visibility problem refers to when multiple threads operate a variable at the same time. After one thread modifies the value of the variable, other threads Modifications of variables cannot be perceived, which is a memory visibility problem. Using volatile can solve the memory visibility problem, such as the following code, when volatile is not added, its implementation is as follows:
private static boolean flag = false; public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { @Override public void run() { // 如果 flag 变量为 true 就终止执行 while (!flag) { } System.out.println("终止执行"); } }); t1.start(); // 1s 之后将 flag 变量的值修改为 true Thread t2 = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("设置 flag 变量的值为 true!"); flag = true; } }); t2.start(); }
The execution results of the above program As follows:
However, after the above program has been executed for N times, it still has not ended. This shows that after thread 2 modified the flag variable, thread 1 did not Variable modifications are perceived.
Then next, we try to add volatile to the flag. The implementation code is as follows:
public class volatileTest { private static volatile boolean flag = false; public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { @Override public void run() { // 如果 flag 变量为 true 就终止执行 while (!flag) { } System.out.println("终止执行"); } }); t1.start(); // 1s 之后将 flag 变量的值修改为 true Thread t2 = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("设置 flag 变量的值为 true!"); flag = true; } }); t2.start(); } }
The execution results of the above program are as follows:
From the above execution results, we can see that using volatile can solve the memory visibility problem in the program.
1.2 Preventing instruction reordering
Instruction reordering means that during program execution, the compiler or JVM often reorders instructions to improve the execution performance of the program. The original design intention of instruction reordering is indeed very good, and it can also play a great role in a single thread. However, in multi-threads, using instruction reordering may cause thread safety issues.
The so-called thread safety problem refers to the execution result of the program that does not match our expectations. For example, if the correct result we expected is 0, but the execution result of the program is 1, then this is a thread safety issue.
Using volatile can prohibit instruction reordering, thereby ensuring that the program can be executed correctly when running in multiple threads.
2. Why use volatile?
Back to the topic, we use volatile in singleton mode, mainly because volatile can prohibit instruction reordering, thereby ensuring the normal operation of the program . Some readers may ask questions here, isn't synchronized already used to ensure thread safety? So why add volatile? Look at the following code:
public class Singleton { private Singleton() {} // 使用 volatile 禁止指令重排序 private static volatile Singleton instance = null; public static Singleton getInstance() { if (instance == null) { // ① synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); // ② } } } return instance; } }
Pay attention to the above code. I marked the two lines of code at ① and ②. Adding volatile to private variables is mainly to prevent the reordering of instructions during the execution of ②, that is, the execution of "instance = new Singleton()". This line of code seems to be just a process of creating an object, but it The actual execution is divided into the following 3 steps:
Create memory space.
#Initialize the object Singleton in the memory space.
#Assign the memory address to the instance object (after executing this step, instance will not be equal to null).
Just imagine, If volatile is not added, then thread 1 may execute the instruction reordering when executing the ② of the above code, changing the original The execution order of 1, 2, and 3 is rearranged to 1, 3, and 2. But in special circumstances, after thread 1 has executed step 3, if thread 2 comes and executes the first step of the above code, it is judged that the instance object is not null, but thread 1 has not yet finished instantiating the object. Then Thread 2 will get a "half" object that is instantiated, causing a program execution error. This is why volatile is added to the private variable.
The above is the detailed content of Why does the volatile keyword need to be added to Java singleton mode?. For more information, please follow other related articles on the PHP Chinese website!

Cloud computing significantly improves Java's platform independence. 1) Java code is compiled into bytecode and executed by the JVM on different operating systems to ensure cross-platform operation. 2) Use Docker and Kubernetes to deploy Java applications to improve portability and scalability.

Java'splatformindependenceallowsdeveloperstowritecodeonceandrunitonanydeviceorOSwithaJVM.Thisisachievedthroughcompilingtobytecode,whichtheJVMinterpretsorcompilesatruntime.ThisfeaturehassignificantlyboostedJava'sadoptionduetocross-platformdeployment,s

Containerization technologies such as Docker enhance rather than replace Java's platform independence. 1) Ensure consistency across environments, 2) Manage dependencies, including specific JVM versions, 3) Simplify the deployment process to make Java applications more adaptable and manageable.

JRE is the environment in which Java applications run, and its function is to enable Java programs to run on different operating systems without recompiling. The working principle of JRE includes JVM executing bytecode, class library provides predefined classes and methods, configuration files and resource files to set up the running environment.

JVM ensures efficient Java programs run through automatic memory management and garbage collection. 1) Memory allocation: Allocate memory in the heap for new objects. 2) Reference count: Track object references and detect garbage. 3) Garbage recycling: Use the tag-clear, tag-tidy or copy algorithm to recycle objects that are no longer referenced.

Start Spring using IntelliJIDEAUltimate version...

When using MyBatis-Plus or other ORM frameworks for database operations, it is often necessary to construct query conditions based on the attribute name of the entity class. If you manually every time...

Java...


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

WebStorm Mac version
Useful JavaScript development tools

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

Notepad++7.3.1
Easy-to-use and free code editor