java|迅速了解JDK线程池以及Spring线程池

??对于经常创建和销毁,使用量特别大的资源,比如并发情况下的线程,对性能影响非常大。所以我们一般?提前创建好多个线程,放入线程池中,使用时直接获取,使用完放入池中。可以避免频繁创建销毁,实现重复利用。
【java|迅速了解JDK线程池以及Spring线程池】好处:

  • 提高响应速度(减少创建新线程的时间)
  • 降低资源消耗(重复利用线程池中的线程,不需要每次都创建)
  • 便于线程管理
    • 线程池大小
    • 最大线程数
对于Java多线程不是很熟悉的可以先去一篇看懂Java多线程
JDK自带的线程池(常用的有两个)
  • ExecutorService (这是一个普通的线程池,能够创建普通的线程)
  • ScheduledExecutorService(这个线程池创建的线程,每隔一段时间执行一个任务,它可以执行那种间隔的任务)
public class ThreadPoolTest { //JDK普通线程池 private ExecutorService executorService = Executors.newFixedThreadPool(5); //JDK可执行定时任务的线程池 private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5); //在main方法中启动线程,如果这个线程不挂掉的话,这个main会等待它执行,不会立刻就结束。 // 但是Test方法,Junit方法不一样,它启动的子线程和当前线程是并发的,test方法后面如果没有逻辑,它立刻就结束了。 //解决办法:在test方法启动一个线程以后想等一会,等他执行完以后在结束,可以让主线程或者当前线程sleep一会,阻塞一会 //又因为sleep老是抛异常,为了调起来方便一点,稍微封装一下。 private void sleep(long m){ try{ Thread.sleep(m); }catch (InterruptedException e){ e.printStackTrace(); } }//JDK普通线程池 @Test public void test(){ Runnable task = new Runnable() { @Override public void run() { logger.debug("Hello ExecutorService"); } }; for (int i = 0; i < 10; i++) { executorService.submit(task); //每调用一次这个submit方法,就会分配一个线程来执行这个线程体。 } sleep(10000); }//JDK定时任务线程池 @Test public void test1(){ Runnable task = new Runnable() { @Override public void run() { logger.debug("Hello scheduledExecutorService"); } }; //scheduleAtFixedRate以固定的频率去执行 //scheduleWithFixedDelay以固定的一个延迟去执行 scheduledExecutorService.scheduleAtFixedRate(task,10000,1000, TimeUnit.MILLISECONDS); sleep(30000); } }

Spring 线程池
  • ThreadPoolTaskExecutor(一个普通的线程池,创建普通的线程)
  • ThreadPoolTaskScheduler(创建的线程可以执行定时任务。)
@SpringBootTest public class ThreadPoolTest { //spring框架已经初始化好了,并且放入容器中了。 //spring普通线程池 @Autowired private ThreadPoolTaskExecutor taskExecutor; //spring 可以执行定时任务的线程池。 @Autowired private ThreadPoolTaskScheduler taskScheduler; private void sleep(long m){ try{ Thread.sleep(m); }catch (InterruptedException e){ e.printStackTrace(); } } //spring 普通线程池 @Test public void test2(){ Runnable task = new Runnable() { @Override public void run() { logger.debug("Hello ThreadPoolTaskExecutor"); } }; for (int i = 0; i < 10; i++) { taskExecutor.submit(task); } sleep(10000); }//spring 定时任务线程池 @Test public void test3(){ Runnable task = new Runnable() { @Override public void run() { logger.debug("Hello ThreadPoolTaskScheduler"); } }; Date startTime = new Date(System.currentTimeMillis() + 10000); taskScheduler.scheduleAtFixedRate(task, startTime, 1000); //默认以毫秒为单位 sleep(30000); } }

在application.properties中的配置如下:
# TaskExecutionProperties(普通线程池) # 核心线程数 spring.task.execution.pool.core-size=5 # 最大线程数 spring.task.execution.pool.max-size=15 # 队列的容量,如果15个还不够,就把任务先放在队列里,等有空闲线程了再分配。 spring.task.execution.pool.queue-capacity=100# TaskSchedulingProperties(可执行定时任务的线程池) spring.task.scheduling.pool.size=5

    推荐阅读