乐趣区

关于java:SpringBoot之使用Async进行异步处理

除了应用默认线程池外,能够自定义应用的线程池(举荐)
定义线程池
第一步,先在 Spring Boot 主类中定义一个线程池,比方:

@EnableAsync
    @Configuration
    class TaskPoolConfig {@Bean("taskExecutor")
        public Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(10);
            executor.setMaxPoolSize(20);
            executor.setQueueCapacity(200);
            executor.setKeepAliveSeconds(60);
            executor.setThreadNamePrefix("taskExecutor-");
            executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            return executor;
        }
    }

下面咱们通过应用 ThreadPoolTaskExecutor 创立了一个线程池,同时设置了以下这些参数:

  • 外围线程数 10:线程池创立时候初始化的线程数
  • 最大线程数 20:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过外围线程数的线程
  • 缓冲队列 200:用来缓冲执行工作的队列
  • 容许线程的闲暇工夫 60 秒:当超过了外围线程出之外的线程在闲暇工夫达到之后会被销毁
  • 线程池名的前缀:设置好了之后能够不便咱们定位解决工作所在的线程池
  • 线程池对回绝工作的解决策略:这里采纳了 CallerRunsPolicy 策略,当线程池没有解决能力的时候,该策略会间接在 execute 办法的调用线程中运行被回绝的工作;如果执行程序已敞开,则会抛弃该工作
  • 在定义了线程池之后,咱们如何让异步调用的执行工作应用这个线程池中的资源来运行呢?办法非常简单,咱们只须要在 @Async 注解中指定线程池名即可,比方:
@Slf4j
@Component
public class Task {public static Random random = new Random();

    @Async("taskExecutor")
    public void doTaskOne() throws Exception {log.info("开始做工作一");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("实现工作一,耗时:" + (end - start) + "毫秒");
    }

    @Async("taskExecutor")
    public void doTaskTwo() throws Exception {log.info("开始做工作二");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("实现工作二,耗时:" + (end - start) + "毫秒");
    }

    @Async("taskExecutor")
    public void doTaskThree() throws Exception {log.info("开始做工作三");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("实现工作三,耗时:" + (end - start) + "毫秒");
    }

}

单元测试
最初,咱们来写个单元测试来验证一下

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

    @Autowired
    private Task task;

    @Test
    public void test() throws Exception {task.doTaskOne();
        task.doTaskTwo();
        task.doTaskThree();
        //join 办法的作用是阻塞,即期待线程完结,才继续执行。Thread.currentThread().join();
    }

}
退出移动版