Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

Author’s other platforms:

| CSDN:blog.csdn.net/qq_4115394…

| the nuggets: juejin. Cn/user / 651387…

| zhihu: www.zhihu.com/people/1024…

| GitHub:github.com/JiangXia-10…

| public no. : 1024 notes

This article is about 2,681 words and takes 7 minutes to read

1 introduction

A question often encountered in written interviews: is the Spring Controller singleton or multi-instance?

The first answer is: Controllers are singletons by default. Don’t use non-static member variables, or you’ll mess up your data logic. And because of the singleton, it’s not thread-safe.

So how can Spring ensure concurrency safety since it is not thread-safe?

2 the body

Let’s start with the following example:

package com.springboot.springbootdemo.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ScopeController { public int number = 0; @RequestMapping("/text1") public int test1(){ number=number+1; return number; } @RequestMapping("/text2") public int test2(){ number=number+1; return ++number; }}Copy the code

Can find our first visit to http://localhost:8080/text1, the answer is 1; Then we visit http://localhost:8080/text2 again, the answer is 2. So you get different values, which proves that this is thread unsafe.

Spring’s bean scope can be found in the previous article: Portal Spring Notes (3) : @scope sets component scope.

In Spring annotation development, the @scope annotation can be used to set the Scope of a component. Through the @scope source code, it can be found that the @Scope annotation has five scopes, namely:

SINGLETON: SINGLETON, default, REQUEST: creates one instance for each REQUEST SESSION: creates one instance for each SESSION GLOBAL SESSION: creates a GLOBAL Web domain Similar to Application in servlets.Copy the code

By default, the Controller is a singleton, which is unsafe because it causes property reuse.

@Scope(“prototype”)

package com.springboot.springbootdemo.controller; import org.springframework.context.annotation.Scope; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @Scope("prototype") public class ScopeController { public int number = 0; @RequestMapping("/text1") public String test1(){ number=number+1; return String.valueOf(number); } @RequestMapping("/text2") public String test2(){ number=number+1; return String.valueOf(number); }}Copy the code

Can find our first visit to http://localhost:8080/text1, the answer is 1; Then we visit http://localhost:8080/text2 again, the answer is 1. This is thread-safe.

3 summary

From the above examples, it can be concluded that:

1. Spring controllers default to singleton mode, which is not thread safe, so do not define member variables in controller mode.

2. In singleton mode, thread safety can be addressed by using ThreadLocal.

Thread-safety issues are mainly caused by global and static variables. If a global variable or static variable is read and no write is performed on each thread, the global variable is generally thread-safe. If multiple threads execute write operations at the same time, consider thread synchronization. Otherwise, thread safety is affected. Spring uses ThreadLocal to synchronize shared resources with high concurrency.

ThreadLocal provides a copy of the value for each thread that uses the variable, so that each thread can change its own copy independently without interfering with other threads’ copies. From the thread’s point of view, it is as if each line owns the variable entirely.

ThreadLocal maintains a copy of each variable as follows:

public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map ! = null) map.set(this, value); else createMap(t, value); }Copy the code

3. With the @scope (” prototype “) annotation, change the default Scope to multi-example mode. This allows you to define non-static member variables in controller.

Controllers in Spring are singletons by default for two reasons:

(1) For performance: Singletons do not need to be created every time

(2) No need for multiple singletons: as long as the controller does not define attributes, then singletons are completely safe and usable. If they are defined, then they will definitely have competing access. If you must define it, set it to multi-example mode by annotating @scope (“prototype”).

Today’s recommendation

Check how often SQL statements are executed

How to locate inefficient SQL execution

Explain the execution plan

Use the Trace tool to analyze the optimizer execution plan

SQL optimization techniques: Show Profile

Several must master SQL optimization skills (six) : for SQL statement optimization