03. spring 线程池与异步编程

线程池创建类

package org.pzy.spring.complex;

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

import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import lombok.Data;

@Component
@Configurable
@ConfigurationProperties(prefix = "myThreadPool")
@Data
public class ThreadPoolConfiguration {

  private int corePoolSize;
  private int maxPoolSize;
  private int queueCapacity;
  private int keepAliveSeconds;

  @Bean
  public Executor testMyThreadPool01() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(corePoolSize);
    executor.setMaxPoolSize(maxPoolSize);
    executor.setQueueCapacity(queueCapacity);
    executor.setKeepAliveSeconds(keepAliveSeconds);
    executor.setThreadNamePrefix("my-thread-pool-01");
    // 当线程池已满,且等待队列也满了的时候,转为主线程执行
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    executor.initialize();
    return executor;
  }

  @Bean
  public Executor testMyThreadPool02() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(corePoolSize);
    executor.setMaxPoolSize(maxPoolSize);
    executor.setQueueCapacity(queueCapacity);
    executor.setKeepAliveSeconds(keepAliveSeconds);
    executor.setThreadNamePrefix("my-thread-pool-02");
    // 当线程池已满,且等待队列也满了的时候,抛出TaskRejectedException
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
    executor.initialize();
    return executor;
  }

  @Bean
  public Executor testMyThreadPool03() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(corePoolSize);
    executor.setMaxPoolSize(maxPoolSize);
    executor.setQueueCapacity(queueCapacity);
    executor.setKeepAliveSeconds(keepAliveSeconds);
    executor.setThreadNamePrefix("my-thread-pool-03");
    // 当线程池已满,且等待队列也满了的时候,抛弃一个在等待队列中等待的时间最久的线程,并将当前线程放入等待队列(不会抛出异常)
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
    executor.initialize();
    return executor;
  }

  @Bean
  public Executor testMyThreadPool04() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(corePoolSize);
    executor.setMaxPoolSize(maxPoolSize);
    executor.setQueueCapacity(queueCapacity);
    executor.setKeepAliveSeconds(keepAliveSeconds);
    executor.setThreadNamePrefix("my-thread-pool-04");
    // 当线程池已满,且等待队列也满了的时候,直接抛弃当前线程(不会抛出异常)
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
    executor.initialize();
    return executor;
  }
}

使用线程池

package org.pzy.spring.complex.bean;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class TestService {

  @Async("testMyThreadPool01")
  public void say(int id) throws InterruptedException {
    System.out.println(Thread.currentThread().getName() + " " + Thread.currentThread().getId() + " --> " + id);
    Thread.sleep(2 * 1000);
  }

  @Async("testMyThreadPool02")
  public void say02(int id) throws InterruptedException {
    System.out.println(Thread.currentThread().getName() + " " + Thread.currentThread().getId() + " --> " + id);
    Thread.sleep(2 * 1000);
  }

  @Async("testMyThreadPool03")
  public void say03(int id) throws InterruptedException {
    System.out.println(Thread.currentThread().getName() + " " + Thread.currentThread().getId() + " --> " + id);
    Thread.sleep(2 * 1000);
  }

  @Async("testMyThreadPool04")
  public void say04(int id) throws InterruptedException {
    System.out.println(Thread.currentThread().getName() + " " + Thread.currentThread().getId() + " --> " + id);
    Thread.sleep(2 * 1000);
  }
}

测试类

package org.pzy.spring.complex;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.pzy.spring.complex.bean.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class AppTest {

  @Autowired
  private TestService testService;

  @Test
  public void test() throws InterruptedException {
    for (int i = 0; i < 10; i++) {
      testService.say(i);
    }
    Thread.sleep(10000 * 1000);
  }

  @Test
  public void test02() throws InterruptedException {
    for (int i = 0; i < 10; i++) {
      testService.say02(i);
    }
    Thread.sleep(10000 * 1000);
  }
  
  @Test
  public void test03() throws InterruptedException {
    for (int i = 0; i < 10; i++) {
      testService.say03(i);
    }
    Thread.sleep(10000 * 1000);
  }
  
  @Test
  public void test04() throws InterruptedException {
    for (int i = 0; i < 10; i++) {
      testService.say04(i);
    }
    Thread.sleep(10000 * 1000);
  }
}

配置文件

server:
  port: 56000
myThreadPool:
  corePoolSize: 1   # 核心线程池大小
  maxPoolSize: 3    # 最大线程池大小
  queueCapacity: 2  # 等待队列大小
  keepAliveSeconds: 3 # 空闲线程存活时间

启动类

package org.pzy.spring.complex;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync //启用异步编程
public class App {
  public static void main(String[] args) {
    SpringApplication.run(App.class);
  }
}

代码详见: https://gitee.com/free_pan/spring-summary/tree/master/spring-complex-04

你可能感兴趣的:(03. spring 线程池与异步编程)