1. 程式人生 > >springboot 多線程執行

springboot 多線程執行

city oot 接口 interrupt initial keepal ring inter easy

一.springboot開線程執行異步任務

1.Spring通過任務執行器TaskExecutor,來實現多線程和並發編程,使用ThreadPoolTaskExecutor可實現一個基於線程池的TaskExecutor; 2.異步需要在配置類上面加@EnableAsync 來開啟對異步任務的支持在需要異步執行的方法上面加@Async 來聲明這個方法是一個需要異步執行的方法; 3.讓配置類實現AsyncConfigurer接口,並重寫getAsyncExecutor方法,並返回一個ThreasPoolTaskExecutor,就可以獲取一個基於線程池的TaskExecutor; 4.@Async 用在方法上
,表示這個方法是一個異步的方法,如果用在類上面,表明這個類中的所有方法都是異步的方法。

(1).配置類

 1 package com.yunzhangfang.springboot1.config;
 2 
 3 import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
 4 import org.springframework.context.annotation.ComponentScan;
 5 import org.springframework.context.annotation.Configuration;
6 import org.springframework.scheduling.annotation.AsyncConfigurer; 7 import org.springframework.scheduling.annotation.EnableAsync; 8 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 9 10 import java.util.concurrent.Executor; 11 12 @Configuration 13 @ComponentScan("com.yunzhangfang.springboot1.service")
14 @EnableAsync 15 public class ThreadConfig implements AsyncConfigurer { 16 17 // ThredPoolTaskExcutor的處理流程 18 // 當池子大小小於corePoolSize,就新建線程,並處理請求 19 // 當池子大小等於corePoolSize,把請求放入workQueue中,池子裏的空閑線程就去workQueue中取任務並處理 20 // 當workQueue放不下任務時,就新建線程入池,並處理請求,如果池子大小撐到了maximumPoolSize,就用RejectedExecutionHandler來做拒絕處理 21 // 當池子的線程數大於corePoolSize時,多余的線程會等待keepAliveTime長時間,如果無請求可處理就自行銷毀 22 @Override 23 public Executor getAsyncExecutor() { 24 ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 25 executor.setCorePoolSize(5); 26 executor.setMaxPoolSize(15); 27 executor.setQueueCapacity(25); 28 executor.initialize(); 29 return executor; 30 } 31 32 @Override 33 public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { 34 return null; 35 } 36 37 }

(2).異步任務

 1 package com.yunzhangfang.springboot1.service;
 2 
 3 import org.springframework.scheduling.annotation.Async;
 4 import org.springframework.scheduling.annotation.AsyncResult;
 5 import org.springframework.stereotype.Service;
 6 
 7 import java.util.concurrent.Future;
 8 
 9 @Service
10 public class TaskService {
11 
12     @Async
13     /**
14      * 表明是異步調用
15      * 沒有返回值
16      */
17     public void excutVoidTask(int i) {
18         System.out.println("異步執行任務第[" + i + "] 個");
19     }
20 
21     /**
22      * 有返回值
23      * 異常調用
24      *
25      * @param i
26      * @return
27      * @throws InterruptedException
28      */
29     @Async
30     public Future<String> excuteValueTask(int i) throws InterruptedException {
31         Thread.sleep(1000);
32         Future<String> future = new AsyncResult<String>("success is " + i);
33         System.out.println("異步執行任務第[" + i + "] 個");
34         return future;
35     }
36 
37 }

(3).測試異步任務

 1 package com.yunzhangfang.springboot1;
 2 
 3 import com.yunzhangfang.springboot1.service.TaskService;
 4 import org.junit.Test;
 5 import org.junit.runner.RunWith;
 6 import org.springframework.beans.factory.annotation.Autowired;
 7 import org.springframework.boot.test.context.SpringBootTest;
 8 import org.springframework.core.task.TaskRejectedException;
 9 import org.springframework.test.context.junit4.SpringRunner;
10 
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.concurrent.ExecutionException;
14 import java.util.concurrent.Future;
15 
16 @RunWith(SpringRunner.class)
17 @SpringBootTest
18 public class Springboot1ApplicationTests {
19 
20     @Autowired
21     private TaskService service;
22 
23     @Test
24     public void contextLoads() {
25     }
26 
27     /**
28      * 沒有返回值測試
29      */
30     @Test
31     public void testVoid() {
32         for (int i = 0; i < 20; i++) {
33             service.excutVoidTask(i);
34         }
35         System.out.println("========主線程執行完畢=========");
36     }
37 
38     @Test
39     public void testReturn() throws InterruptedException, ExecutionException {
40         List<Future<String>> lstFuture = new ArrayList<>();// 存放所有的線程,用於獲取結果
41         for (int i = 0; i < 100; i++) {
42             while (true) {
43                 try {
44                     // 線程池超過最大線程數時,會拋出TaskRejectedException,則等待1s,直到不拋出異常為止
45                     Future<String> stringFuture = service.excuteValueTask(i);
46                     lstFuture.add(stringFuture);
47                     break;
48                 } catch (TaskRejectedException e) {
49                     System.out.println("線程池滿,等待1S。");
50                     Thread.sleep(1000);
51                 }
52             }
53         }
54 
55         // 獲取值.get是阻塞式,等待當前線程完成才返回值
56         for (Future<String> future : lstFuture) {
57             System.out.println(future.get());
58         }
59 
60         System.out.println("========主線程執行完畢=========");
61     }
62 
63 }

有錯誤,希望指出,共同進步,天天向上

springboot 多線程執行