SpringBoot implements multithreading

1 thread synchronous and asynchronous

Thread synchronization: Thread A wants to request a certain resource, but this resource is being used by thread B. Because of the existence of the synchronization mechanism, A can only wait. It takes a long time and has high security.

Thread asynchronous: A thread wants to request a certain resource, but this resource is being used by B thread, because there is no synchronization mechanism, A thread still requests it.

Multiple irrelevant processes started by one process, the relationship between them is asynchronous; synchronization must be executed to the end before other operations can be performed, and asynchronous execution can be performed at the same time.

Synchronization is required when multiple threads execute, but no synchronization is required if it is a single thread.

2 async instances

The main method and the called method must be of different classes to achieve multi-threading.

2.1 Startup class

Use @EnableAsync to enable SpringBoot’s support for asynchronous tasks.

Application:

@SpringBootApplication</code><code>@EnableAsync</code><code>public class Application {<!-- --></code><code> public static void main(String[] args) { <!-- --></code><code> SpringApplication.run(Application.class, args);</code><code> }</code><code>}

2.2 Thread pool

The configuration class implements the interface AsyncConfigurator and returns a ThreadPoolTaskExecutor thread pool object.

config/AsyncConfig:

@Configuration</code><code>@EnableAsync</code><code>public class AsyncConfig implements AsyncConfigurer {<!-- --></code>
<code> // Processing flow of ThredPoolTaskExcutor</code><code> // When the pool size is smaller than corePoolSize, create a new thread and process the request</code><code> // When the pool size is equal to corePoolSize, put the request into In the workQueue, the idle threads in the pool will go to the workQueue to fetch tasks and process them</code><code> // When the workQueue can't put down the task, create a new thread into the pool and process the request. If the pool size reaches the maximumPoolSize, it will Use RejectedExecutionHandler to do rejection processing</code><code> // When the number of threads in the pool is greater than corePoolSize, the extra threads will wait for keepAliveTime for a long time, and destroy themselves if there is no request to process</code>
<code> @Override</code><code> @Bean</code><code> public Executor getAsyncExecutor() {<!-- --></code><code> ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();</code><code> // Number of core threads: number of threads initialized when the thread pool is created</code><code> executor.setCorePoolSize(10);</code><code> // Maximum number of threads: thread pool The maximum number of threads, only after the buffer queue is full, will apply for threads exceeding the number of core threads</code><code> executor.setMaxPoolSize(100);</code><code> // Buffer queue: used to buffer execution Queue of tasks</code><code> executor.setQueueCapacity(50);</code><code> // Thread pool shutdown: wait for all tasks to complete before closing</code><code> executor.setWaitForTasksToCompleteOnShutdown(true) ;</code><code> // Waiting time: Forced stop after waiting for 5 seconds Out-of-the-box threads will be destroyed after 60 seconds.</code><code> executor.setKeepAliveSeconds(60);</code><code> // thread name prefix</code><code> executor.setThreadNamePrefix("learn- Async-");</code><code> // Initialize thread</code><code> executor.initialize();</code><code> return executor;</code><code> }</code>
<code> @Override</code><code> public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {<!-- --></code><code> return null;</code><code> }</code><code> }

2.3 controller

Test Async calls through this layer.

@RestController</code><code>@RequestMapping("/homepage")</code><code>public class AsyncController {<!-- --></code><code> @Autowired</code><code> AsyncService asyncTaskService;</code><code> @GetMapping("/learnAsync")</code><code> public String learnAsync(){<!-- --></code><code> for (int i = 0; i < 10; i ++ ) {<!-- --></code><code> asyncTaskService.executeAsyncTask(i);</code><code> }</code><code> return "1";</code><code> }</code><code>}

2.4 service

The @Async annotation indicates that the method is an asynchronous method. If the annotation is on the class, it indicates that all methods in this class are asynchronous.

@Service</code><code>public class AsyncService {<!-- --></code><code> private final static Logger logger = LoggerFactory.getLogger(com.spring.boot.service.AsyncService. class);</code><code> @Async // Indicates that the method is an asynchronous method. If the annotation is on the class, it means that all methods in the class are asynchronous</code><code> public void executeAsyncTask(int i) {<!-- --></code><code> logger.info(" \t complete task" + i);</code><code> System.out.println("Thread" + Thread.currentThread().getName() + "execute asynchronous task: " + i);</code> <code>}</code><code>}

2.5 output

3 Future classes

Modify the service layer to use synchronous calls, asynchronous calls without return, and asynchronous calls using Future to return.

3.1 Synchronous call

public long subBySync() throws Exception {<!-- --></code><code> long start = System.currentTimeMillis();</code><code> long sum = 0;</code> <code> long end = System.currentTimeMillis();</code><code> sum = end - start;</code><code> return sum;</code><code>}

3.2 Asynchronous call without return

@Async</code><code>public void subByVoid() throws Exception {<!-- --></code><code> long start = System.currentTimeMillis();</code><code> long sum = 0;</code><code> long end = System.currentTimeMillis();</code><code> sum = end - start;</code><code>}

3.3 Asynchronous call Future return

controller:

Future<Long> task = asyncTaskService.subByAsync();

service:

@Async</code><code>public Future<Long> subByAsync() throws Exception {<!-- --></code><code> long start = System.currentTimeMillis();</code> <code> long sum = 0;</code><code> long end = System.currentTimeMillis();</code><code> sum = end - start;</code><code> return new AsyncResult<>( sum);</code><code>}

4 CompletableFuture class

If an error occurs when using Future:

Unable to determine the type parameter of org.springframework.scheduling.annotation.AsyncResult<>

No instance of type variable V exists, making org.springframework.scheduling.annotation.AsyncResult conform to XXX

You can use the CompletableFuture class:

@Asyncpublic </code><code>CompletableFuture<Map<String, Object>> subByAsyncMap() throws Exception {<!-- --></code><code> Map<String, Object> res = new HashMap<>();</code><code> return CompletableFuture.completedFuture(res);</code><code>}

5 thread closed

When the number of threads exceeds the number of core threads, the old threads that have finished running will be closed.

It can be tested by timing tasks.

batch/ScheduledTaskService:

@Component</code><code>@EnableScheduling</code><code>public class ScheduledTaskService {<!-- --></code><code> @Autowired</code><code> AsyncService asyncService ;</code><code> @Scheduled(cron = "1/1 * * * * ? ") //1s once</code><code> public void learnCron(){<!-- --></code><code> asyncService. learnScheduledAsync();</code><code> }</code><code>}

Add method in AsyncService:

// Use the scheduled task to call this method to create a thread</code><code>@Async</code><code>public void learnScheduledAsync(){<!-- --></code><code> Long timeLong = System.currentTimeMillis();</code><code> SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //Set format</code><code> String timeString = timeFormat .format(timeLong);</code><code> System.out.println("Thread" + Thread.currentThread().getName());</code><code> System.out.println("timeString: " + timeString + "\
");</code><code>}

The number of core threads has been set to 10 in the asynchronous configuration (AsyncConfig):

//Number of core threads: the number of threads initialized when the thread pool is created</code><code>executor.setCorePoolSize(10);

You can observe the output by running. After the number of threads reaches 10, it will start from 1 again.

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge Java skill treeHomepageOverview 108415 people are studying systematically