电子商务网站规划与建设论文,建设工程网站教程,个人养老保险怎么查询,硬件开发方案JavaSE-线程池#xff08;5#xff09;- 建议使用的方式 
虽然JDK Executors 工具类提供了默认的创建线程池的方法#xff0c;但一般建议自定义线程池参数#xff0c;下面是阿里巴巴开发手册给出的理由#xff1a; 另外Spring也提供了线程池的实现#xff0c;比如 Thread…JavaSE-线程池5- 建议使用的方式 
虽然JDK Executors 工具类提供了默认的创建线程池的方法但一般建议自定义线程池参数下面是阿里巴巴开发手册给出的理由 另外Spring也提供了线程池的实现比如 ThreadPoolExecutor 
ThreadPoolExecutor 
如下初始化一个核心线程数为 2 最大线程数为 4队列长度为 2 的线程池其中 initialize 为线程池具体初始化方法 
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.ThreadPoolExecutor;public class ThreadPoolTaskExecutorTest {static class MyTask implements Runnable {private int i;public MyTask(int i) {this.i  i;}Overridepublic void run() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread()     i);}}public static void main(String[] args) {ThreadPoolTaskExecutor executor  new ThreadPoolTaskExecutor();//设置核心线程数executor.setCorePoolSize(2);//设置最大线程数executor.setMaxPoolSize(4);//设置线程被回收的空闲时长executor.setKeepAliveSeconds(6);//设置队列容量executor.setQueueCapacity(2);//设置线程前缀executor.setThreadNamePrefix(t-);//设置拒绝策略executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());//初始化线程池executor.initialize();for (int i  1; i  8; i) {try {executor.execute(new MyTask(i));} catch (Exception e) {e.printStackTrace();}}}
}由打印结果可以看出7,8任务由于线程数达到 maxPoolSize且队列也填充满线程池执行了拒绝策略 
18:47:12.134 [main] INFO org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor - Initializing ExecutorService
org.springframework.core.task.TaskRejectedException: Executor [java.util.concurrent.ThreadPoolExecutor63e2203c[Running, pool size  4, active threads  4, queued tasks  2, completed tasks  0]] did not accept task: com.hs.example.base.multithread.threadpool.ThreadPoolTaskExecutorTest$MyTask3224f60bat org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor.execute(ThreadPoolTaskExecutor.java:317)at com.hs.example.base.multithread.threadpool.ThreadPoolTaskExecutorTest.main(ThreadPoolTaskExecutorTest.java:39)
Caused by: java.util.concurrent.RejectedExecutionException: Task com.hs.example.base.multithread.threadpool.ThreadPoolTaskExecutorTest$MyTask3224f60b rejected from java.util.concurrent.ThreadPoolExecutor63e2203c[Running, pool size  4, active threads  4, queued tasks  2, completed tasks  0]at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)at org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor.execute(ThreadPoolTaskExecutor.java:314)... 1 more
org.springframework.core.task.TaskRejectedException: Executor [java.util.concurrent.ThreadPoolExecutor63e2203c[Running, pool size  4, active threads  4, queued tasks  2, completed tasks  0]] did not accept task: com.hs.example.base.multithread.threadpool.ThreadPoolTaskExecutorTest$MyTask4bbfb90aat org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor.execute(ThreadPoolTaskExecutor.java:317)at com.hs.example.base.multithread.threadpool.ThreadPoolTaskExecutorTest.main(ThreadPoolTaskExecutorTest.java:39)
Caused by: java.util.concurrent.RejectedExecutionException: Task com.hs.example.base.multithread.threadpool.ThreadPoolTaskExecutorTest$MyTask4bbfb90a rejected from java.util.concurrent.ThreadPoolExecutor63e2203c[Running, pool size  4, active threads  4, queued tasks  2, completed tasks  0]at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)at org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor.execute(ThreadPoolTaskExecutor.java:314)... 1 more
Thread[t-4,5,main] 6
Thread[t-1,5,main] 1
Thread[t-3,5,main] 5
Thread[t-2,5,main] 2
Thread[t-3,5,main] 3
Thread[t-4,5,main] 4ThreadPoolTaskExecutor initialize 方法 
在上述例子中initialize 方法是线程池初始化的具体实现源码如下 
public void initialize() {if (this.logger.isInfoEnabled()) {this.logger.info(Initializing ExecutorService  (this.beanName ! null ?    this.beanName   : ));}if (!this.threadNamePrefixSet  this.beanName ! null) {this.setThreadNamePrefix(this.beanName  -);}。this.executor  this.initializeExecutor(this.threadFactory, this.rejectedExecutionHandler);
}由以下代码可以看出 ThreadPoolExecutor 是对 ThreadPoolExecutor 的封装其中 this.threadFactory即为 ThreadPoolExecutor 本身由下面的类结构图可以看出 ThreadPoolExecutor 继承自 ExecutorConfigurationSupport而ExecutorConfigurationSupport实现了 ThreadFactory 接口 
protected ExecutorService initializeExecutor(ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {BlockingQueueRunnable queue  this.createQueue(this.queueCapacity);ThreadPoolExecutor executor;if (this.taskDecorator ! null) {executor  new ThreadPoolExecutor(this.corePoolSize, this.maxPoolSize, (long)this.keepAliveSeconds, TimeUnit.SECONDS, queue, threadFactory, rejectedExecutionHandler) {public void execute(Runnable command) {Runnable decorated  ThreadPoolTaskExecutor.this.taskDecorator.decorate(command);if (decorated ! command) {ThreadPoolTaskExecutor.this.decoratedTaskMap.put(decorated, command);}super.execute(decorated);}};} else {executor  new ThreadPoolExecutor(this.corePoolSize, this.maxPoolSize, (long)this.keepAliveSeconds, TimeUnit.SECONDS, queue, threadFactory, rejectedExecutionHandler);}if (this.allowCoreThreadTimeOut) {executor.allowCoreThreadTimeOut(true);}this.threadPoolExecutor  executor;return executor;
}ThreadPoolTaskExecutor 类结构图  
直接注入ThreadPoolTaskExecutor 
除了手动实例化 ThreadPoolTaskExecutor 外也可以直接注入 ThreadPoolTaskExecutor 如下例 
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.test.context.junit4.SpringRunner;import java.util.concurrent.CountDownLatch;RunWith(SpringRunner.class)
SpringBootTest
public class ThreadPoolTaskExecutorTests {static class MyTask implements Runnable {private int i;private CountDownLatch countDownLatch;public MyTask(int i, CountDownLatch countDownLatch) {this.i  i;this.countDownLatch  countDownLatch;}Overridepublic void run() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread()     i);countDownLatch.countDown();}}Autowiredprivate ThreadPoolTaskExecutor taskExecutor;Testpublic void contextLoads() {CountDownLatch countDownLatch  new CountDownLatch(8);long start  System.currentTimeMillis();for (int i  1; i  8; i) {try {taskExecutor.execute(new MyTask(i, countDownLatch));} catch (Exception e) {e.printStackTrace();}}try {countDownLatch.await();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(耗时  (System.currentTimeMillis() - start));}}2023-02-19 21:25:15.219  INFO 123964 --- [           main] c.h.e.aop.ThreadPoolTaskExecutorTests    : Starting ThreadPoolTaskExecutorTests on 0IZV69K0AKR0ELX with PID 123964 (started by Administrator in D:\workspace\idea_workspace\idea-test\example\2-aop)
2023-02-19 21:25:15.220  INFO 123964 --- [           main] c.h.e.aop.ThreadPoolTaskExecutorTests    : No active profile set, falling back to default profiles: default
2023-02-19 21:25:16.349  INFO 123964 --- [           main] c.h.e.aop.ThreadPoolTaskExecutorTests    : Started ThreadPoolTaskExecutorTests in 1.571 seconds (JVM running for 3.269)
2023-02-19 21:25:16.382  INFO 123964 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService applicationTaskExecutor
Thread[task-8,5,main] 8
Thread[task-6,5,main] 6
Thread[task-4,5,main] 4
Thread[task-2,5,main] 2
Thread[task-3,5,main] 3
Thread[task-5,5,main] 5
Thread[task-7,5,main] 7
Thread[task-1,5,main] 1
耗时1005
2023-02-19 21:25:17.637  INFO 123964 --- [       Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService applicationTaskExecutor之所以可以直接使用 ThreadPoolTaskExecutor 是因为SpringBoot自动注入了此类具体看 org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration 
package org.springframework.boot.autoconfigure.task;import java.util.concurrent.Executor;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.task.TaskExecutionProperties.Pool;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.task.TaskExecutorBuilder;
import org.springframework.boot.task.TaskExecutorCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.task.TaskDecorator;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;ConditionalOnClass({ThreadPoolTaskExecutor.class})
Configuration
EnableConfigurationProperties({TaskExecutionProperties.class})
public class TaskExecutionAutoConfiguration {public static final String APPLICATION_TASK_EXECUTOR_BEAN_NAME  applicationTaskExecutor;private final TaskExecutionProperties properties;private final ObjectProviderTaskExecutorCustomizer taskExecutorCustomizers;private final ObjectProviderTaskDecorator taskDecorator;public TaskExecutionAutoConfiguration(TaskExecutionProperties properties, ObjectProviderTaskExecutorCustomizer taskExecutorCustomizers, ObjectProviderTaskDecorator taskDecorator) {this.properties  properties;this.taskExecutorCustomizers  taskExecutorCustomizers;this.taskDecorator  taskDecorator;}BeanConditionalOnMissingBeanpublic TaskExecutorBuilder taskExecutorBuilder() {Pool pool  this.properties.getPool();TaskExecutorBuilder builder  new TaskExecutorBuilder();builder  builder.queueCapacity(pool.getQueueCapacity());builder  builder.corePoolSize(pool.getCoreSize());builder  builder.maxPoolSize(pool.getMaxSize());builder  builder.allowCoreThreadTimeOut(pool.isAllowCoreThreadTimeout());builder  builder.keepAlive(pool.getKeepAlive());builder  builder.threadNamePrefix(this.properties.getThreadNamePrefix());builder  builder.customizers(this.taskExecutorCustomizers);builder  builder.taskDecorator((TaskDecorator)this.taskDecorator.getIfUnique());return builder;}//实例化 ThreadPoolTaskExecutor LazyBean(name  {applicationTaskExecutor, taskExecutor})ConditionalOnMissingBean({Executor.class})public ThreadPoolTaskExecutor applicationTaskExecutor(TaskExecutorBuilder builder) {return builder.build();}
}默认配置 TaskExecutionProperties  
ConfigurationProperties(spring.task.execution)
public class TaskExecutionProperties {private final TaskExecutionProperties.Pool pool  new TaskExecutionProperties.Pool();private String threadNamePrefix  task-;public TaskExecutionProperties() {}public TaskExecutionProperties.Pool getPool() {return this.pool;}public String getThreadNamePrefix() {return this.threadNamePrefix;}public void setThreadNamePrefix(String threadNamePrefix) {this.threadNamePrefix  threadNamePrefix;}public static class Pool {private int queueCapacity  2147483647;private int coreSize  8;private int maxSize  2147483647;private boolean allowCoreThreadTimeout  true;private Duration keepAlive  Duration.ofSeconds(60L);public Pool() {}public int getQueueCapacity() {return this.queueCapacity;}public void setQueueCapacity(int queueCapacity) {this.queueCapacity  queueCapacity;}public int getCoreSize() {return this.coreSize;}public void setCoreSize(int coreSize) {this.coreSize  coreSize;}public int getMaxSize() {return this.maxSize;}public void setMaxSize(int maxSize) {this.maxSize  maxSize;}public boolean isAllowCoreThreadTimeout() {return this.allowCoreThreadTimeout;}public void setAllowCoreThreadTimeout(boolean allowCoreThreadTimeout) {this.allowCoreThreadTimeout  allowCoreThreadTimeout;}public Duration getKeepAlive() {return this.keepAlive;}public void setKeepAlive(Duration keepAlive) {this.keepAlive  keepAlive;}}
}