This is the first day of my participation in Gwen Challenge

Question origin

When I was browsing the resources and saw that Spring’s default singleton mode is to manage Bean objects, I wondered, is there a thread safety issue here?

Summary of information and own understanding

Singletons and multiple cases

  • Objects in the Spring container are implemented singleton by default
  • Multiple instances can be implemented explicitly using the @Scope(“prototype”) annotation
  • The singleton single instance calls a method to create an object at IOC startup and puts it into the container, retrieving the same bean from the container Map each subsequent invocation
  • Prototype multi-instance does not call methods to create objects when IOC starts, but instead creates objects each time it is called

Example: Multi-instance mode

@Scope("prototype") public class MultViewController { private static int st = 0; private int index = 0; @RequestMapping("/test") public String test() { System.out.println(st++ + " | " + index++); return "/lsh/ch5/test"; }}Copy the code

Their usage scenarios

Singletons are used because there is no need to create a new object for each request, which wastes both CPU and memory

Multiple cases are used to prevent concurrency problems; That is, one request changes the state of the object, which in turn processes another request, and the previous request changes the state of the object, which causes the object to incorrectly process the other request

Multiple cases are used when the object has changeable state, singleton is used otherwise

Thread safety in singleton mode

Controllers in Spring are singleton by default, so you can’t use non-static member variables in a Controller, otherwise data logic chaos will occur, which is thread unsafe

Several solutions:

  1. Do not define member variables in controller
  2. In case you have to define a non-static member variable, use the @scope (” prototype “) annotation to set it to multi-example mode
  3. Use the ThreadLocal variable in the Controller

The underlying principles of singletons

Here are some ideas for doing back-end and iOS development on your own:

  1. So methods or functions, function code in C is stored in memory structure in code area, and when you do multithreading, each thread creates local variables in its own frame, and then executes the code line by line according to the entry of the code area; In object-oriented languages, such as c + + or Java, actually has not changed much in the underlying memory structure, the core principle is the same, it will be in the Java class method extracted, still on the area code, just two different: during compilation of the internal name contains the name of the class information, the second is the calling class method, the default will reduce the class object Passed in as a parameter, it is the same as the underlying mechanism of C
  2. Singleton pattern is the only create a class in the application object, if the class method only to a local variable operation, multiple threads to influence each other between each other, then this is thread-safe, which is the most suitable for the singleton pattern, because from the underlying code originally, is still within each thread to generate a local variable, each other, and then remit at the entrance of their execution method step by step Code, such as method implementation is from mysql, then this is thread-safe, can be executed in singleton mode, the query does not affect each other; Another example, such as the network component in ios, is to create an instance of AFKManager for each Controller to send requests instead of using the singleton pattern because each Controller logs request status data

Local variables are not affected by multithreading

For singleton classes that run in multiple threads, such as servlets in Web applications, operations on local variables in each method are done in the thread’s own independent memory area, so they are thread-safe

Member variables are affected by multiple threads

Member variables of a class are affected by multiple threads. Since class objects are created using new, they are placed on the stack. The member variables in a class object are stored in memory in a particular order, so in a class method, because the address of the class object is passed in as the first argument, you can access the values of the member variables in the stack. So multithreaded access is not secure

How does the JVM implement separate memory space for threads

  1. Each time a thread is enabled, the JVM assigns it a Java stack that holds the running state of the current thread in frames. The method that a thread is executing is called the current method, the stack frame that the current method uses is called the current frame, and the class that the current method belongs to is called the current class
  2. Each time a thread calls a Java method, the JVM pushes a frame on the stack corresponding to that thread, and that frame becomes the current frame. When the method executes, it uses the frame to store parameters, local variables, intermediate results, and so on.
  3. All data on the Java stack is private. No thread can access another thread’s stack data. So we don’t have to worry about stack access synchronization in multi-threaded cases.

ThreadLocal

Java supports thread-safe singleton patterns with ThreadLocal:

There is an API in Java called ThreadLocal that is used in Spring singleton mode to switch parameters between threads. ThreadLocal is used to ensure thread-safety. In fact, the key of a ThreadLoacal is the Thread instance of the current Thread. In singleton mode, Spring puts the values of each thread’s possible thread-safety parameters into ThreadLocal. This is a single instance operation, but the data in different threads is isolated from each other, because there are far fewer beans created and destroyed at run time, so this approach consumes less memory resources in most scenarios, and the higher the concurrency, the greater the advantage.

Advantages of the singleton pattern

Singletons greatly save instance creation and destruction, which improves performance, while ThreadLocal is used to ensure thread-safety

The singleton mode is recommended by Spring. It can greatly save resources and improve service resilience under high concurrency. Spring IOC’s bean manager is “absolutely thread-safe.”