動態

詳情 返回 返回

SpringBoot使用異步@EnableAsync、@Async - 動態 詳情

Spring boot通過@EnableAsync@Async配合來實現異步調用的。

舉一個理髮店的例子吧,比如3位理髮師,5位顧客來理髮。

下面上代碼

通過@EnableAsync@Configuration配置一個默認的線程池,充當理髮師
CorePoolSize(3);即3位理髮師


import org.springframework.aop.interceptor.AsyncExecutionAspectSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@EnableAsync
@Configuration
public class ThreadPoolConfig {

    @Bean(name = AsyncExecutionAspectSupport.DEFAULT_TASK_EXECUTOR_BEAN_NAME)
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(3);
        executor.setMaxPoolSize(3);
        executor.setQueueCapacity(10);
        executor.setKeepAliveSeconds(60);
        executor.setThreadGroupName("理髮師-");
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
}

理髮業務,haircut方法上面添加 @Async(value = "taskExecutor")表示方法異步,異步的方法不能被當前類的方法互相調用,在同一個類內部調用一個異步方法,不會觸發異步

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.concurrent.CountDownLatch;

@Service
@Slf4j
public class DemoServiceImpl {

    @Async(value = "taskExecutor")
    public void haircut(CountDownLatch countDownLatch, String user) {
        log.info("用户:{},開始理髮", user);
        try {
            //模擬耗時
            Thread.sleep(5000L);
        } catch (InterruptedException e) {
        }
        log.info("用户:{},理髮完成", user);
        countDownLatch.countDown();
    }
}

寫一個單側,營業開始,5為顧客來理髮,都理髮完成,營業結束


import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.concurrent.CountDownLatch;

@SpringBootTest
@Slf4j
public class DemoServiceImplTest {

    @Autowired
    private DemoServiceImpl demoService;

    @Test
    public void haircutBusiness() {
        log.info("理髮店:開始營業");
        CountDownLatch countDownLatch = new CountDownLatch(5);
        demoService.haircut(countDownLatch, "張三");
        demoService.haircut(countDownLatch, "李四");
        demoService.haircut(countDownLatch, "王五");
        demoService.haircut(countDownLatch, "馬六");
        demoService.haircut(countDownLatch, "孫七");
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
        }
        log.info("理髮店:關閉營業");
    }
}

運行結果如下:時間點和效果符合預期

CountDownLatch 定義了5個顧客同時來理髮,實際併發還是按照線程池配置3個理髮師來處理的

2022-10-19 18:04:10.356 [main] INFO  org.sauceggplant.manage.demo.service.impl.DemoServiceImplTest[19] - 理髮店:開始營業
2022-10-19 18:04:10.363 [taskExecutor-1] INFO  org.sauceggplant.manage.demo.service.impl.DemoServiceImpl[15] - 用户:張三,開始理髮
2022-10-19 18:04:10.363 [taskExecutor-2] INFO  org.sauceggplant.manage.demo.service.impl.DemoServiceImpl[15] - 用户:李四,開始理髮
2022-10-19 18:04:10.363 [taskExecutor-3] INFO  org.sauceggplant.manage.demo.service.impl.DemoServiceImpl[15] - 用户:王五,開始理髮
2022-10-19 18:04:15.379 [taskExecutor-3] INFO  org.sauceggplant.manage.demo.service.impl.DemoServiceImpl[20] - 用户:王五,理髮完成
2022-10-19 18:04:15.379 [taskExecutor-3] INFO  org.sauceggplant.manage.demo.service.impl.DemoServiceImpl[15] - 用户:馬六,開始理髮
2022-10-19 18:04:15.379 [taskExecutor-1] INFO  org.sauceggplant.manage.demo.service.impl.DemoServiceImpl[20] - 用户:張三,理髮完成
2022-10-19 18:04:15.380 [taskExecutor-2] INFO  org.sauceggplant.manage.demo.service.impl.DemoServiceImpl[20] - 用户:李四,理髮完成
2022-10-19 18:04:15.380 [taskExecutor-1] INFO  org.sauceggplant.manage.demo.service.impl.DemoServiceImpl[15] - 用户:孫七,開始理髮
2022-10-19 18:04:20.380 [taskExecutor-3] INFO  org.sauceggplant.manage.demo.service.impl.DemoServiceImpl[20] - 用户:馬六,理髮完成
2022-10-19 18:04:20.380 [taskExecutor-1] INFO  org.sauceggplant.manage.demo.service.impl.DemoServiceImpl[20] - 用户:孫七,理髮完成
2022-10-19 18:04:20.381 [main] INFO  org.sauceggplant.manage.demo.service.impl.DemoServiceImplTest[29] - 理髮店:關閉營業

感興趣童鞋可以自己試一下,good luck!

Add a new 評論

Some HTML is okay.