Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to solve the failure of JDK double check lock

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces the JDK double check lock failure how to solve the relevant knowledge, the content is detailed and easy to understand, the operation is simple and fast, has a certain reference value, I believe that you read this JDK double check lock failure how to solve the article will have a harvest, let's take a look at it.

Double-checked locking is more common in the singleton mode with delayed initialization (there are many ways to implement the singleton mode. This is the only way to illustrate the problem of double-checked locking). Let's take a look at a version:

Public class Singleton {private static Singleton instance = null; private Singleton () {} public static Singleton getInstance () {if (instance = = null) {instance = new Singleton ();} return instance;}}

The above is the most primitive schema, and you can see at a glance that multiple Singleton instances may be generated in a multithreaded environment, so there is a synchronized version of it:

Public class Singleton {private static Singleton instance = null; private Singleton () {} public synchronized static Singleton getInstance () {if (instance = = null) {instance = new Singleton ();} return instance;}}

In this version, each call to getInstance requires a lock on the Singleton.class, but the lock is only necessary when you start to build the Singleton object, and subsequent multithreaded access will be less efficient, so there is the following version:

Public class Singleton {private static Singleton instance = null; private Singleton () {} public static Singleton getInstance () {if (instance = = null) {synchronized (Singleton.class) {if (instance = = null) {instance = new Singleton ();} return instance }}

Good idea! Unfortunately, the solution also fails to solve the root of the problem:

The reason is that the order in which the Singleton is initialized and the object address is written to the instance field is uncertain. In the case of a thread new Singleton (), memory space is allocated to the object and its fields are set to the default value before the constructor is called. At this point, you can assign the allocated memory address to the instance field, but the object may not have been initialized; at this point, if another thread calls getInstance, you will get the object in the incorrect state.

For the above reasons, the following solutions may be proposed:

Public class Singleton {private static Singleton instance = null; private Singleton () {} public static Singleton getInstance () {if (instance = = null) {Singleton temp; synchronized (Singleton.class) {temp = instance If (temp = = null) {synchronized (Singleton.class) {temp = new Singleton ();} instance = temp;} return instance;}}

This scheme places the construction of the Singleton object in the innermost synchronization block, and the idea is to set a memory barrier when exiting the synchronization block to prevent the reordering of initializing Singleton and writing object addresses to the instance field.

Unfortunately, this idea is also wrong, and the rules of synchronization are not like this. The rule for exiting the monitor (exiting synchronization) is that all actions before exiting the monitor must be completed before releasing the monitor. However, there is no provision that actions after exiting the monitor cannot be completed before exiting the monitor. That is, the code in the synchronization block must be completed when it exits synchronization, while the code behind the synchronization block can be moved to the synchronization block by the compiler or runtime environment to execute.

The compiler can legally and reasonably move instance = temp into the innermost synchronous block, which has the same problem as the previous version.

In JDK1.5 and subsequent versions, volatile semantics are extended so that the system will not allow reordering of writing to a volatile variable with any previous read and write operations, nor will it allow reading a volatile variable to be reordered with any subsequent read and write operations.

In jdk1.5 and later versions, you can set instance to volatile for double-checked locking to take effect, as follows:

Public class Singleton {private static volatile Singleton instance = null; private Singleton () {} public static Singleton getInstance () {if (instance = = null) {synchronized (Singleton.class) {if (instance = = null) {instance = new Singleton ();} return instance }}

It is important to note that this approach is still problematic in JDK1.4 and previous versions.

This is the end of the article on "how to solve the problem of JDK double check lock failure". Thank you for reading! I believe that everyone has a certain understanding of the knowledge of "how to solve the failure of JDK double check lock". If you want to learn more knowledge, you are welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report