美文网首页
Android线程池

Android线程池

作者: 人世看客 | 来源:发表于2022-05-18 18:09 被阅读0次

一、为什么要用线程池

目前就我在Android开发工作中,实际自己写线程用到线程池真的很少,但是又不得不去了解下线程池。线程池直白点就是管理线程的一个工具,平时我们创建子线程可能直接用Thread方法创建一个子线程就完事了。

Thread{
   //需要执行的耗时代码
}.start()

当然,如果是简单的单线程,不需要使用线程池的。牵扯多线程时推荐试用线程池,比如我们常见的多个文件同时下载。会牵扯到多个线程创建执行,如果处理不好,会导致大量线程创建和销毁,这样会造成资源浪费,使性能降低。这时候就需要用到线程池去管理线程

二、线程池原理

线程池是一个池子,里面能容纳多个线程。线程池帮助我们管理线程的创建、复用、销毁;具体啥时候创建,何时复用,什么时候销毁;需要根据ThreadPoolExecutor类的构造参数去实现

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

参数说明:

  • corePoolSize: 核心线程数量,存活情况有两种:1.当allowCoreThreadTimeout = flase (默认)时 ,核心线程会伴随线程池的整个生命周期一直存活;2.当allowCoreThreadTimeout = true 时,空闲时长超过 keepAliveTime设置的时长,会被销毁。
  • maximumPoolSize:最大线程数,可以理解为线程池容纳线程最大个数。
  • keepAliveTime:允许空闲时长,超出这个时长,非核心线程会被销毁(非核心线程 = maximumPoolSize - corePoolSize),核心线程会不会被销毁还需要看参数allowCoreThreadTimeout是否为true
  • unit:时间单位,与keepAliveTime参数有关
  • workQueue:任务队列,线程池中的线程没有空闲时,多余的任务会放任务队列中等待

下面代码是一个实例:

 val threadPoolExecutor =
            ThreadPoolExecutor(2, 4, 1, TimeUnit.SECONDS, LinkedBlockingQueue<Runnable>(6))
        findViewById<View>(R.id.btn5).setOnClickListener{
            for (i in 1..10) {
                threadPoolExecutor.execute{
                    Thread.sleep(3000)
                    Log.e("print","当前线程个数:$i, 线程名:${Thread.currentThread().name}")
                }
            }
        }

核心线程数为2,最大线程数为4,超时1秒,任务队列长度6个。任务总数10个
注意:这里有个公式(任务队列总数 + 最大线程数 >= 任务总数),这个公式必须成立,不然会报错java.util.concurrent.RejectedExecutionException

运行结果:

log1

等待几秒再运行for循环中代码打印日志

log2

分析日志1:
一共10个任务,程序会先创建2个核心线程去领2个任务执行,还剩下8个任务。而任务队列长度只有6,还有剩余两个任务没法放入,这时候就会创建非核心线程去执行这两个任务(这里允许最大线程数为4,已经创建了2个核心线程,刚好还可以创建2个非核心线程,也就是我前面说的那个公式必须成立,如果这里最大线程数小于4,就会报错)。看日志刚好一共创建了4条线程,后面的都是复用这4条线程去执行

分析日志2:
因为等待了几秒,超过了我们设置的超时时间1秒。线程池会回收两个非核心线程。从日志可以看出线程1和3被回收了(非核心线程),复用了线程2和4(核心线程),然后又创建了两个新的线程5和6

三、介绍几种常见线程池

  • Executors.newFixedThreadPool(2) 核心线程池,用此方法创建的线程池只有核心线程
  • Executors.newCachedThreadPool() 非核心线程池,用此方法创建的线程池只有非核心线程
  • Executors.newSingleThreadExecutor() 单线程池,用此方法创建的线程池只有一个核心线程
  • Executors.newScheduledThreadPool(5) 调度线程池,用此方法创建的线程池可设置核心线程,非核心线程为最大值

几种方式底层都是实现ThreadPoolExecutor构造参数

相关文章

  • 线程池创建和相关知识

    线程池创建(单例):Android线程池得要这么用 - 简书 线程池相关知识:Android开发之线程池使用总结 ...

  • Android线程池的使用

    一、线程与线程池,为什么要使用线程池 1、Android中的线程 在Android中有主线程和子线程的区分。主线程...

  • 线程池

    话题:线程池Android中的线程池有哪些?它们的区别是什么?为什么要使用线程池? 线程是Android里面一个很...

  • 笔记:Android线程和线程池

    Android线程和线程池 Android中的线程操作相关的类有 AsyncTask IntentService ...

  • 第十九周 线程池

    话题:线程池 Android 中的线程池有哪些?它们的区别是什么?为什么要使用线程池?关键字:线程池、Thread...

  • Android 多线程:线程池理解和使用总结

    一、Android线程池介绍 1.1 原理 Android中的线程池概念来源于Java中的Executor,Exe...

  • Android面试之线程和线程池

    Android中的线程形态 AsyncTask底层用到了线程池。AsyncTask封装了线程池和Handler,它...

  • Android多线程规划

    Android上的线程池使用 Android线程 特性 Each thread costs a minimum o...

  • 19. 线程池

    Android 中的线程池就是 java 中的线程池,即 ThreadPoolExecutor 类。 Java 通...

  • Android的线程和线程池

    Android的线程和线程池 标签(空格分隔): android 一些概念: 线程分类:主线程和子线程,主线程主要...

网友评论

      本文标题:Android线程池

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