美文网首页线程池
线程池的使用

线程池的使用

作者: Dr_Time | 来源:发表于2020-03-04 11:27 被阅读0次

回顾线程的基本知识

我们最常见的创建线程的几种方法:一是继承Thread类,二是实现Runnable的接口,三是实现Callable接口。单个线程的创建和销毁会消耗机器资源,如果线程数量多的话,频繁的创建和销毁会大大的降低程序运行的效率,耗费大量的内存,因为正常来说线程执行完毕后死亡,会被当作垃圾回收。怎么能让线程复用、统一管理命名线程、提高资源的使用率?线程池就能完美的解决这个问题。

为什么使用线程池

线程池是一种多线程处理形式,处理过程中将任务添加到队列,线程池在工程启动时并不会立即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务。执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。
简而言之,线程池就是一组线程的集合。

线程池实现原理

SpringBoot配置线程池

首先在启动类中配置如下Bean

   @Bean("defaultThreadPool")
   public ThreadPoolExecutor defaultThreadPool() {
        log.info("start asyncServiceExecutor");

        ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("HiveMetric-pool-%d").build();

        //  核心线程数
        int corePoolSize = 10;

        //  配置最大线程数
        int maximumPoolSize = 20;

        //  当线程数大于内核数时,这是多余的空闲线程将在终止之前等待新任务的最长时间
        long keepAliveTime = 2L;

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime,
                TimeUnit.SECONDS, new LinkedBlockingQueue<>(1024), threadFactory, new ThreadPoolExecutor.AbortPolicy());
        log.info("线程池,{}", threadPoolExecutor);

        return threadPoolExecutor;
    }

1)首先创建一个ThreadFactoryBuilder给线程统一命名,方便管理及检索日志;
2)通过ThreadPoolExecutor来创建一个线程池,该类来自于JUC包下,下面介绍一下重要的几个参数;
corePoolSize:核心线程数量
maximumPoolSize:线程池中的线程总数=核心线程数+非核心线程数
keepAliveTime:当线程数大于内核数时,多余的空闲线程将在终止之前等待新任务的最长时间。
TimeUnit:时间单位
BlockingQueue<Runnable>:在执行任务之前用于保留任务的队列。
ThreadFactory:线程工厂
RejectedExecutionHandler:因为达到了线程界限和队列容量而在执行被阻止时使用的处理器。线程池中的线程已经用完了,无法继续为新任务服务,同时,等待队列也已经排满了,再也塞不下新任务了。这时候我们就需要拒绝策略机制合理的处理这个问题。JDK 内置的拒绝策略如下:

  • AbortPolicy : 直接抛出异常,阻止系统正常运行。
  • CallerRunsPolicy : 只要线程池未关闭,该策略直接在调用者线程中,运行当前被丢弃的
    任务。显然这样做不会真的丢弃任务,但是,任务提交线程的性能极有可能会急剧下降。
  • DiscardOldestPolicy : 丢弃最老的一个请求,也就是即将被执行的一个任务,并尝试再
    次提交当前任务。
  • DiscardPolicy : 该策略默默地丢弃无法处理的任务,不予任何处理。如果允许任务丢
    失,这是最好的一种方案。
    以上内置拒绝策略均实现了 RejectedExecutionHandler 接口,若以上策略仍无法满足实际需要,完全可以自己扩展RejectedExecutionHandler 接口。
    3)在service层通过如下方法注入
    @Autowired
    private ThreadPoolExecutor defaultThreadPool;

ThreadPoolExecutor继承自AbstractExecutorService,下面看一下submit()。

    /**
     * @throws RejectedExecutionException {@inheritDoc}
     * @throws NullPointerException       {@inheritDoc}
     */
    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }

最后通过Future<V>get()的方法取出线程的执行结果。

        for (HostEntity hostEntity : hiveServer2Info) {
            String hostName = hostEntity.getHostName();
            Future<JSONObject> submit = defaultThreadPool.submit(() -> stringConvertJsonObject(hostName, getJmxFileContent(hostName, metricFileLocation)));
            map.put(hostName, submit);
        }

        for (Map.Entry<String, Future<JSONObject>> next : map.entrySet()) {
            String hostName = next.getKey();
            try {
                result.put(hostName, next.getValue().get());
            } catch (Exception e) {
                log.error("线程池获取返回结果异常!主机名:{}", hostName, e);
            }
        }

之前从多台服务器解析文件由串行改为线程池并行的解决方法,初步优化之后线上接口的响应时间由10s+降为1s。

相关文章

  • Java线程池的使用

    线程类型: 固定线程 cached线程 定时线程 固定线程池使用 cache线程池使用 定时调度线程池使用

  • java----线程池

    什么是线程池 为什么要使用线程池 线程池的处理逻辑 如何使用线程池 如何合理配置线程池的大小 结语 什么是线程池 ...

  • spring 线程池和java线程池

    jdk线程池就是使用jdk线程工具类ThreadPoolExecutor 创建线程池spring线程池就是使用自己...

  • Spring @Async开启异步任务

    定义线程池 使用线程池

  • 八、线程池剖析

    一、前置问题 线程的状态转换 为什么要使用线程池 线程池的继承体系 线程池使用的场景 线程数的设置规则 线程池的状...

  • 1203-AsyncTask详解一:线程池的基本设置

    AsyncTask的内部使用线程池处理并发,要了解它是怎样使用线程池的,那要先了解线程池的基本设置 线程池的基本参...

  • ExecutorService shutdown()和shutd

    ExecutorService是我们经常使用的线程池,当我们使用完线程池后,需要关闭线程池。ExecutorSer...

  • java 线程池使用和详解

    线程池的使用 构造方法 corePoolSize:线程池维护线程的最少数量 maximumPoolSize:线程池...

  • java线程池

    线程VS线程池 普通线程使用 创建线程池 执行任务 执行完毕,释放线程对象 线程池 创建线程池 拿线程池线程去执行...

  • Android中的线程池

    前言 提到线程池,我们先说一下使用线程池的好处。使用线程池的优点可以概括为:1、重复使用线程池中的线程,避免因为线...

网友评论

    本文标题:线程池的使用

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