动态

详情 返回 返回

Spring ThreadPoolTaskExecutor解説 - 动态 详情

1、ThreadPoolTaskExecutor @Async示例

@Async 註解的作用

  1. 異步執行方法:
    被 @Async 註解標記的方法會在一個獨立的線程中執行,而不是在調用者的線程中。這意味着調用方法時,調用者線程會立即返回,並且方法的實際執行會在後台進行
  2. 提高併發性和性能:
    通過異步執行耗時的操作,可以提高應用程序的響應速度和吞吐量。例如,在Web應用中,可以異步處理後台任務,從而更快地響應用户請求
  3. 分離任務執行:
    可以將一些不需要立即返回結果的任務(例如發送郵件、寫日誌等)異步執行,從而提高應用的整體效率

    1.1、引入依賴

    確保你的項目中引入了Spring的相關依賴。對於Maven項目,pom.xml中需要包含以下依賴:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
  <version>2.7.3</version>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <version>2.7.3</version>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-configuration-processor</artifactId>
  <version>2.7.3</version>
</dependency>

1.2、ThreadPoolTaskExecutor配置類

@Configuration
public class AppConfig {

    @Bean(name = "taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.setThreadNamePrefix("MyExecutor-");
        executor.initialize();
        return executor;
    }
}

1.3、@Async ThreadPoolTaskExecutor執行任務

@Service
public class TaskService {

    @Autowired
    private Executor taskExecutor;

    @Async("taskExecutor")
    public void executeTask(int i) {
        System.out.println("Task " + i + " is running on thread " + Thread.currentThread().getName());
    }
}

1.4、啓用異步支持

為了讓Spring支持異步調用,需要在配置類中啓用異步支持:

@Configuration
@EnableAsync
public class AsyncConfig {
}

1.5、啓動任務 & 結果

@SpringBootApplication
public class Application implements CommandLineRunner {

    @Autowired
    private TaskService taskService;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... args) {
        for (int i = 0; i < 10; i++) {
            taskService.executeTask(i);
        }
    }
}

結果如下 :

Task 0 is running on thread MyExecutor-1
Task 2 is running on thread MyExecutor-3
Task 3 is running on thread MyExecutor-4
Task 7 is running on thread MyExecutor-4
Task 4 is running on thread MyExecutor-5
Task 8 is running on thread MyExecutor-4
Task 6 is running on thread MyExecutor-3
Task 1 is running on thread MyExecutor-2
Task 5 is running on thread MyExecutor-1
Task 9 is running on thread MyExecutor-5

1.6、不使用@Async註解的任務提交

@Service
public class TaskService {

    @Autowired
    private Executor taskExecutor;

//    @Async("taskExecutor")
//    public void executeTask(int i) {
//        System.out.println("Task " + i + " is running on thread " + Thread.currentThread().getName());
//    }

    public void executeTask(int i) {
        taskExecutor.execute(() -> {
            System.out.println("Task " + i + " is running on thread " + Thread.currentThread().getName());
        });
    }
}

2、ThreadPoolTaskExecutor submitListenable

2.1、代碼邏輯

@Configuration
public class AppConfig {

    @Bean(name = "taskExecutor")
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.setThreadNamePrefix("MyExecutor-");
        executor.initialize();
        return executor;
    }
}
public class Task implements Callable<String> {

    private final int taskId;

    public Task(int taskId) {
        this.taskId = taskId;
    }

    @Override
    public String call() throws Exception {
        System.out.println("Task " + taskId + " is running on thread " + Thread.currentThread().getName());
        // Simulate a long-running task
        Thread.sleep(1000);
        return "Task " + taskId + " completed";
    }
}
@SpringBootApplication
public class Application implements CommandLineRunner {

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;


    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... args) throws Exception {

        List<ListenableFuture<String>> futures = new ArrayList<>();
        for (int i = 0 ; i < 10 ; i++) {
            Task task = new Task(i);
            ListenableFuture<String> future = taskExecutor.submitListenable(task);
            future.addCallback(new ListenableFutureCallback<String>() {
                @Override
                public void onFailure(Throwable ex) {
                    System.out.println("onFailure ex ->" + ex);
                }

                @Override
                public void onSuccess(String result) {
                    System.out.println("onSuccess  result -> " + result);
                }
            });
        }
    }
}

2.2、結果輸出

Task 0 is running on thread MyExecutor-1
Task 1 is running on thread MyExecutor-2
Task 2 is running on thread MyExecutor-3
Task 3 is running on thread MyExecutor-4
Task 4 is running on thread MyExecutor-5
onSuccess  result -> Task 1 completed
Task 5 is running on thread MyExecutor-2
onSuccess  result -> Task 2 completed
Task 6 is running on thread MyExecutor-3
onSuccess  result -> Task 3 completed
Task 7 is running on thread MyExecutor-4
onSuccess  result -> Task 4 completed
Task 8 is running on thread MyExecutor-5
onSuccess  result -> Task 0 completed
Task 9 is running on thread MyExecutor-1
onSuccess  result -> Task 5 completed
onSuccess  result -> Task 9 completed
onSuccess  result -> Task 6 completed
onSuccess  result -> Task 7 completed
onSuccess  result -> Task 8 completed

如感興趣,點贊加關注,謝謝!!!

user avatar king_wenzhinan 头像 AmbitionGarden 头像 u_16769727 头像 lenglingx 头像 ahahan 头像 huangxunhui 头像 boxuegu 头像 wuliaodechaye 头像 chengxy 头像 javaedge 头像 enaium 头像 wuxiedekeben 头像
点赞 21 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.