Java singleton object synchronization

Source: Internet
Author: User

Link: http://www.ibm.com/developerworks/cn/java/l-singleton/

Singleton is a common design pattern. In Java applications, a singleton object can ensure that only one instance exists in one JVM. Because of this feature, the singleton object is usually used as a carrier for storing configuration information in the program, because it can ensure that other objects read consistent information. For example, in a server program, the configuration information of the server may be stored in a database or file. The configuration data is read by a single instance object in a unified manner, to obtain the configuration information for other objects in the service process, you only need to access the singleton object. This method greatly simplifies Configuration Management in complex environments, especially in multi-threaded environments. However, different application scenarios may also cause some synchronization problems.

This article will discuss several synchronization problems that may occur when a single-sample object is used for configuration information management in a multi-threaded environment, and provide an optional solution for each problem.

Problem description

In a multi-threaded environment, the synchronization problem of Singleton objects is mainly reflected in two aspects: initialization of Singleton objects and attribute update of Singleton objects.

The methods described in this article have the following assumptions:

  1. The properties (or member variables) of a singleton object are obtained through initialization of the singleton object. That is to say, the latest configuration information will be read from the file or database during the initialization of the singleton object.
  2. Other Objects cannot directly change the attributes of a singleton object. The attributes of a singleton object are changed by the configuration file or the configuration database data.

1.1 single-instance object initialization

First, we will discuss the initialization synchronization of the singleton object. The common processing method of Singleton mode is that there is a static member variable in the object and its type is Singleton type itself. If the variable is null, an object of the singleton type is created, and direct the variable to this object. If the variable is not null, use the variable directly.

The process is shown in the following code:

  public class GlobalConfig {    private static GlobalConfig instance = null;    private Vector properties = null;    private GlobalConfig() {      //Load configuration information from DB or file      //Set values for properties    }    public static GlobalConfig getInstance() {      if (instance == null) {        instance = new GlobalConfig();      }      return instance;    }    public Vector getProperties() {      return properties;    }  }


This processing method can run well in single-threaded mode, but may cause problems in multi-threaded mode. If the first thread finds that the member variable is null, it is ready to create an object. This is the second thread, and it also finds that the member variable is null, it also creates a new object. This results in multiple Singleton instances in one JVM. If the member variables of this Singleton type change during the running process, it may cause inconsistency among multiple Singleton type instances, resulting in some strange phenomena. For example, a service process stops multiple thread services by checking a certain attribute of the singleton object. If there are instances of multiple Singleton objects, some thread services will stop, some thread services cannot be stopped.

1.2 updating attributes of a singleton object

Generally, in order to update configuration information in real time, a thread constantly checks the configuration file or configuration database content. Once a change is detected, it is updated to the attributes of the singleton object. When updating this information, it is likely that other threads are reading this information, resulting in unexpected consequences. For example, if the thread service is stopped by using the single-instance object attribute, if the read and write operations are not synchronized when the attribute is updated, the program throws an exception when the attribute is accessed as null.

Back to Top

Solution

2.1 initialization and synchronization of Singleton objects

For initialization synchronization, you can use the following code to solve the problem.

  public class GlobalConfig {    private static GlobalConfig instance = null;    private Vector properties = null;    private GlobalConfig() {      //Load configuration information from DB or file      //Set values for properties    }    private static synchronized void syncInit() {      if (instance == null) {        instance = new GlobalConfig();      }    }    public static GlobalConfig getInstance() {      if (instance == null) {        syncInit();      }      return instance;    }    public Vector getProperties() {      return properties;    }  }


This method introduces the synchronization code, but because the synchronization code will only be executed once or multiple times at the beginning, the performance of the entire system will not be affected.

2.2 single-instance object property update Synchronization

There are two methods to solve 2nd problems:

1. Refer to the reader/writer's handling method.

Set a read counter. Before reading configuration information each time, add 1 to the counter. After reading, subtract 1 from the counter. Data can be updated only when the read counter is 0, and calls to all read attributes must be blocked. The Code is as follows.

  public class GlobalConfig {private static GlobalConfig instance;private Vector properties = null;private boolean isUpdating = false;private int readCount = 0;private GlobalConfig() {  //Load configuration information from DB or file      //Set values for properties}private static synchronized void syncInit() {if (instance == null) {instance = new GlobalConfig();}}public static GlobalConfig getInstance() {if (instance==null) {syncInit();}return instance;}public synchronized void update(String p_data) {syncUpdateIn();//Update properties}private synchronized void syncUpdateIn() {while (readCount > 0) {try {wait();} catch (Exception e) {}}}private synchronized void syncReadIn() {readCount++;}private synchronized void syncReadOut() {readCount--;notifyAll();}public Vector getProperties() {syncReadIn();//Process datasyncReadOut();return properties;}  }


2. Use the "shadow instance" Method

Specifically, when updating properties, another singleton object instance is directly generated. The newly generated singleton object instance reads the latest configuration information from the database or file; then, assign the configuration information to the attributes of the old singleton object. As shown in the following code.

  public class GlobalConfig {    private static GlobalConfig instance = null;    private Vector properties = null;    private GlobalConfig() {      //Load configuration information from DB or file      //Set values for properties    }    private static synchronized void syncInit() {      if (instance = null) {        instance = new GlobalConfig();      }    }    public static GlobalConfig getInstance() {      if (instance = null) {        syncInit();      }      return instance;    }    public Vector getProperties() {      return properties;    }    public void updateProperties() {      //Load updated configuration information by new a GlobalConfig object      GlobalConfig shadow = new GlobalConfig();      properties = shadow.getProperties();    }  }


Note: In the update method, the latest configuration information is obtained from the file or database by generating a new globalconfig instance and stored in the properties attribute.

Compared with the above two methods, the second method is better. First, programming is simpler. Second, there are not so many synchronization operations, which has little impact on performance.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.