我凡是是凭证以下方法封锁线程池的:
- long start = System.currentTimeMillis();
- for (int i = 0; i <= 5; i++) {
- pool.execute(new Job());
- }
- pool.shutdown();
- while (!pool.awaitTermination(1, TimeUnit.SECONDS)) {
- LOGGER.info("线程还在执行。。。");
- }
- long end = System.currentTimeMillis();
- LOGGER.info("一共处理赏罚了【{}】", (end - start));
pool.awaitTermination(1, TimeUnit.SECONDS) 会每隔一秒钟搜查一次是否执行完毕(状态为 TERMINATED),当从 while 轮回退出时就表白线程池已经完全终止了。
SpringBoot 行使线程池
2018 年了,SpringBoot 流行;来看看在 SpringBoot 中该当怎么设置和行使线程池。
既然用了 SpringBoot ,那天然得施展 Spring 的特征,以是必要 Spring 来帮我们打点线程池:
- @Configuration
- public class TreadPoolConfig {
- /**
- * 斲丧行列线程
- * @return
- */
- @Bean(value = "consumerQueueThreadPool")
- public ExecutorService buildConsumerQueueThreadPool(){
- ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
- .setNameFormat("consumer-queue-thread-%d").build();
- ExecutorService pool = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS,
- new ArrayBlockingQueue(5),namedThreadFactory,new ThreadPoolExecutor.AbortPolicy());
- return pool ;
- }
- }
行使时:
- @Resource(name = "consumerQueueThreadPool")
- private ExecutorService consumerQueueThreadPool;
- @Override
- public void execute() {
- //斲丧行列
- for (int i = 0; i < 5; i++) {
- consumerQueueThreadPool.execute(new ConsumerQueueThread());
- }
- }
着实也挺简朴,就是建设了一个线程池的 bean,在行使时直接从 Spring 中取出即可。
监控线程池
谈到了 SpringBoot,也可操作它 actuator 组件来做线程池的监控。
线程怎么说都是稀缺资源,对线程池的监控可以知道本身使命执行的状况、服从等。
关于 actuator 就不再细说了,感乐趣的可以看看这篇,有具体清算过怎样袒露监控端点。
着实 ThreadPool 自己已经提供了不少 api 可以获取线程状态:
许多要领看名字就知道其寄义,只必要将这些信息袒露到 SpringBoot 的监控端点中,我们就可以在可视化页面查察当前的线程池状态了。
乃至我们可以担任线程池扩展个中的几个函数来自界说监控逻辑:
看这些名称和界说都知道,这是让子类来实现的。
可以在线程执行前、后、终止状态执行自界说逻辑。
线程池断绝
线程池看似很柔美,但也会带来一些题目。
假如我们许多营业都依靠于统一个线程池,当个中一个营业由于各类不行控的缘故起因耗损了全部的线程,导致线程池所有占满。
这样其他的营业也就不能正常运转了,这对体系的冲击是庞大的。
好比我们 Tomcat 接管哀求的线程池,假设个中一些相应出格慢,线程资源得不到接纳开释;线程池逐步被占满,最坏的环境就是整个应用都不能提供处事。
以是我们必要将线程池举办断绝。
凡是的做法是凭证营业举办分别:
好比下单的使命用一个线程池,获取数据的使命用另一个线程池。这样纵然个中一个呈现题目把线程池耗尽,那也不会影响其他的使命运行。
hystrix 断绝
这样的需求 Hystrix 已经帮我们实现了。
Hystrix 是一款开源的容错插件,具有依靠断绝、体系容错降级等成果。
下面来看看 Hystrix 简朴的应用:
起首必要界说两个线程池,别离用于执行订单、处理赏罚用户。
- /**
- * Function:订单处事
- *
- * @author crossoverJie
- * Date: 2018/7/28 16:43
- * @since JDK 1.8
- */
- public class CommandOrder extends HystrixCommand<String> {
- private final static Logger LOGGER = LoggerFactory.getLogger(CommandOrder.class);
- private String orderName;
- public CommandOrder(String orderName) {
- super(Setter.withGroupKey(
- //处事分组
- HystrixCommandGroupKey.Factory.asKey("OrderGroup"))
- //线程分组
- .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("OrderPool"))
- //线程池设置
- .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
- .withCoreSize(10)
- .withKeepAliveTimeMinutes(5)
- .withMaxQueueSize(10)
- .withQueueSizeRejectionThreshold(10000))
- .andCommandPropertiesDefaults(
- HystrixCommandProperties.Setter()
- .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD))
- )
- ;
- this.orderName = orderName;
- }
- @Override
- public String run() throws Exception {
- LOGGER.info("orderName=[{}]", orderName);
- TimeUnit.MILLISECONDS.sleep(100);
- return "OrderName=" + orderName;
- }
- }
- /**
- * Function:用户处事
- *
- * @author crossoverJie
- * Date: 2018/7/28 16:43
- * @since JDK 1.8
- */
- public class CommandUser extends HystrixCommand<String> {
- private final static Logger LOGGER = LoggerFactory.getLogger(CommandUser.class);
- private String userName;
- public CommandUser(String userName) {
- super(Setter.withGroupKey(
- //处事分组
- HystrixCommandGroupKey.Factory.asKey("UserGroup"))
- //线程分组
- .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("UserPool"))
- //线程池设置
- .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
- .withCoreSize(10)
- .withKeepAliveTimeMinutes(5)
- .withMaxQueueSize(10)
- .withQueueSizeRejectionThreshold(10000))
- //线程池断绝
- .andCommandPropertiesDefaults(
- HystrixCommandProperties.Setter()
- .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD))
- )
- ;
- this.userName = userName;
- }
- @Override
- public String run() throws Exception {
- LOGGER.info("userName=[{}]", userName);
- TimeUnit.MILLISECONDS.sleep(100);
- return "userName=" + userName;
- }
- }
api 出格简捷易懂,详细详情请查察官方文档。 (编辑:湖南网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|