Memory, thread safety, and concurrency

Source: Internet
Author: User
Tags class definition

@ Memory mechanism reference from

One, Java memory mechanism
There are 4 types of Java program allocations in memory, namely:

    1. Global Data area: The property that holds the static modifier;
    2. Global code Area: static method for saving static adornments;
    3. Stack memory space: Holds all object names that point to the heap memory space where the object resides;
    4. Heap memory Space: Save object;

Second, the scope of the Java variable:
Java variables are divided into 4 types:

      1. Class variables: Also known as global variables or static variables, you need to use the modifier static decoration, after the class definition allocates memory space, corresponding to the memory of the global data area, without instantiation can be used;
      2. Object variables: Also known as member variables, the memory space is allocated after instantiation before it can be accessed;
      3. A method variable: Also known as a local variable, is a variable defined within a method;
      4. Block variables: is defined within the IF, Fou and other statements inside the variable, its life cycle in the inside of the block, out of the block can not be accessed.

Why use singleton mode?

Because a class returns a reference to an object and an instantiation method, it greatly saves memory and facilitates GC reclamation. (The object is also recycled when null, because Java garbage collection mechanism, Java does not need to be like C or C + + through program code to free up space, and will be reclaimed by the JVM itself, this part of the space when recycling is unpredictable.) @Author)

@ Single-case mode

Typically, a singleton class is designed like this:

 Public classSingleton {/*holds private static instances, prevents references, and assigns null here to enable lazy loading*/    Private StaticSingleton instance =NULL; /*Private constructor method to prevent instantiation*/    PrivateSingleton () {}/*Static engineering methods, creating instances*/     Public StaticSingleton getinstance () {if(Instance = =NULL) {instance=NewSingleton (); }        returninstance; }    /*if the object is used for serialization, you can ensure that the object remains consistent before and after serialization*/     PublicObject readresolve () {returninstance; }}
This class can meet the basic requirements, but, like this without the thread security of the class, if we put it into multi-threaded environment, there must be problems, for the following reasons:

When join threads 1 and 2 are concurrently accessed, if the object is null, the initialization is repeated

The improvement is to add sychronized for thread synchronization,

When instantiating a variable:

 Public Static Singleton getinstance () {        ifnull) {            synchronized  ( Instance) {                ifnull) {                    new  Singleton ();                }            }        }         return instance;    }

This locks up the first time the object is created and is not needed later.

But it's still possible that there will be problems.

creating objects and assigning operations in Java directives is done separately, that is, instance = new Singleton (), and the statements are executed in two steps. However, the JVM does not guarantee the sequencing of the two operations, which means that it is possible for the JVM to allocate space for the new    Singleton instance and then assign the value directly to the instance member before initializing the singleton instance. This can be a mistake, we take a, b two threads as an example: A>a, b thread at the same time entered the first if judgment B>a first into the synchronized block, because instance is null, so it executes instance = new Singleton ();c> Because of the optimization mechanism inside the JVM, the JVM first draws some blank memory allocated to the singleton instance and assigns it to the instance member (note that at this point the JVM does not start initializing the instance), and a leaves the synchronized block. D>b enters the synchronized block because instance is not NULL at this time, so it immediately leaves the synchronized block and returns the result to the program that called the method. E> this time the B thread intends to use the singleton instance, but finds that it was not initialized, and the error occurred.
Deep down to the JVM's understanding, this:

New object when the JVM

A. Allocating memory to an instance

B. Initializing the constructor

C. Point the reference to the allocated memory space (the reference is not NULL)

The general execution order is a->b->c, but due to JVM optimization chaos, it is possible to a->c->b, when another thread accesses, the discovery reference is not NULL, so the corresponding memory operation is returned, then an exception occurs

Above is the lazy mode, a hungry man mode avoids this problem

 Public classSingletontest {//to define a private construction method    Privatesingletontest () {}//set the instance object of itself to a property, plus the static and final modifiers    Private Static FinalSingletontest instance =Newsingletontest (); //static methods return instances of this class     Public Staticsingletontest getinstancei () {returninstance; }  }

A hungry man mode is relatively simple to write, and there is no multithreading synchronization problem, to avoid the performance problems caused by synchronized, but when the class singletontest is loaded, the static instance is initialized, and the statically variable is created and allocated memory space. Since then, this static instance object has been occupying this memory (even if you haven't used it yet), and when the class is unloaded, the static variable is destroyed and the occupied memory is freed, so the memory is consumed under certain conditions. @Author

The reality is that the singleton pattern uses an internal class to maintain the implementation of the Singleton, and the mechanism inside the JVM guarantees that when a class is loaded, the loading process of the class is thread-mutually exclusive.
So when we first call getinstance, the JVM can help us ensure that instance is created only once and that the memory assigned to instance is initialized.
So we don't have to worry about the problem.
。 At the same time, the method will only use the mutex mechanism at the first call,
This solves the problem of low performance. This allows us to briefly summarize a perfect singleton pattern @author:
 Public classSingleton {/*Private constructor method to prevent instantiation*/    PrivateSingleton () {}/*here, an inner class is used to maintain the singleton*/    Private Static classSingletonfactory {Private StaticSingleton instance =NewSingleton (); }    /*Get Instance*/     Public StaticSingleton getinstance () {returnsingletonfactory.instance; }    /*if the object is used for serialization, you can ensure that the object remains consistent before and after serialization*/     PublicObject readresolve () {returngetinstance (); }}

Springmvc default is SingoletoN (singleton mode), multi-threaded, so if the class Zhong contains a state object,

@ Stateful no State

    /*** Stateful bean with state,user properties, and user has Che increased by function, is mutable. *       * @authorPeter Wei **/       Public classStatefulbean { Public intState ; //because user is a reference object in a multithreaded environment, non-thread-safe         Publicuser User;  Public intgetState () {returnState ; }                 Public voidSetState (intState ) {               This. State =State ; }                 PublicUser GetUser () {returnuser; }                 Public voidsetUser (user user) { This. user =user; }      }            /*** Stateless bean, cannot save Che increased by data. Because there is no attribute, it is immutable.      There is only one system of methods to operate. *       * @authorPeter Wei **/       Public classStatelessbeanservice {//Although there is a Billdao attribute, Billdao is a stateless Bean with no state information. Billdao Billdao;  PublicBilldao Getbilldao () {returnBilldao; }                 Public voidSetbilldao (Billdao Billdao) { This. Billdao =Billdao; }                 PublicList<user>Finduser (String Id) {return NULL; }      }  
View Code

The thread is unsafe (single-threaded order, select body, loop body execution, and therefore secure). If you change Singoleton (default) to prototype, you are back to the original question, that is, all requests create new instance objects.

Performance is greatly compromised. So try not to use stateful objects in the controller.

In the comprehensive, multi-threaded concurrent access to SPRINGMVC, in order to ensure that no dirty data, in the premise of Singoleton, should ensure that the controller does not appear in the state object, in the key operations such as order data additions and deletions to change the thread synchronization

(At this point, if the method Sychronized,sql statement does not need a for update lock.) (For update lock after other users can only read, add and delete to change the default is to open the transaction, after completion of automatic commit))

Memory, thread safety, and concurrency

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.