美文网首页
03. spring 线程池与异步编程

03. spring 线程池与异步编程

作者: 码农梦醒 | 来源:发表于2017-12-23 10:11 被阅读131次

    线程池创建类

    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 线程池与异步编程

          本文链接:https://www.haomeiwen.com/subject/fncswxtx.html