【Android 异步操作】线程池 ( 线程池简介 | 线程池初始化方法 | 线程池种类 | AsyncTask 使用线程池示例 )

简介: 【Android 异步操作】线程池 ( 线程池简介 | 线程池初始化方法 | 线程池种类 | AsyncTask 使用线程池示例 )

文章目录

一、线程池简介

二、线程池初始化方法简介

三、线程池使用示例





一、线程池简介


线程池一般是实现了 ExecutorService 接口的类 , 一般使用 ThreadPoolExecutor 线程池 ;



线程池优势 :


减少线程对象个数 : 避免每次执行子线程任务时 , 都要执行 new Thread() 构造函数 , 避免每次创建一个新的对象 , 减少开销 ;


线程管理 : 方面对线程进行管理 , 已存在的线程直接重用 , 这样减少了线程对象创建的个数 , 降低了 CPU 资源开销 ;


控制并发数 : 每个 CPU 都有最合适的并发线程数 , 如果并发数过高 , 就会导致资源竞争 , 线程堵塞 , 合理控制并发数 , 能提高 CPU 使用效率 ;






二、线程池初始化方法简介


线程池初始化方法简介 :


newCachedThreadPool : 创建 可缓存线程池 ; 如果线程池长度超过处理需要 , 则回收线程 , 如果不能回收 , 就创建新线程 ;


newFixedThreadPool : 创建 定长线程池 ; 可以设置线程最大并发数 , 如果并发数已满 , 后续任务会在任务队列中等待 ;


newScheduledThreadPool : 创建 定长周期任务线程池 ; 该线程池支持周期性任务执行 ;


newSingleThreadExecutor : 创建 单线程化线程池 ; 该线程只有一个工作线程 , 可以保证所有任务按照指定的顺序执行 ; 如 FIFO 先进先出顺序 , 或 LIFO 后进先出顺序 ;






三、线程池使用示例


以 AsyncTask 源代码为例 , 在 SerialExecutor 中 , 最终使用的是 THREAD_POOL_EXECUTOR.execute(mActive) 执行线程任务 ; 线程池通过 execute 函数执行外部任务 ;


THREAD_POOL_EXECUTOR 是 自己配置的线程池 , 没有使用 Java 默认提供的四种线程池 , Java 提供的四种线程池是 可缓存线程池 , 定长线程池 , 定长周期任务线程池 , 单线程线程池 ;


THREAD_POOL_EXECUTOR 线程池配置代码如下 :


new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
            TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory,
            new ThreadPoolExecutor.DiscardOldestPolicy());



下面对 THREAD_POOL_EXECUTOR 自己配置的线程池参数进行说明解析 ,


CORE_POOL_SIZE 核心线程数 ,


MAXIMUM_POOL_SIZE 最大线程数 , 非核心线程就是二者相减 ,


KEEP_ALIVE 非核心线程闲置时间 , 超过一定时间非核心线程就会回收 ,


TimeUnit.SECONDS 非核心线程闲置时间单位 “秒” ,


sPoolWorkQueue 线程池任务队列 ,


sThreadFactory 线程工厂 , 作用是用于创建线程




线程池原理说明 :



线程池线程分类 : 线程池的线程分为 核心线程 , 非核心线程 两类 ;


非核心线程闲置时间 : 非核心线程 超过一定的闲置时间 , 就会被回收 ;



假设线程池最大线程数是 8 88 , 核心线程数 3 33 , 非核心线程数 5 55 ;



线程池任务队列 : 当启动一个线程池后 , 线程池会不停地从该任务队列中取出任务执行 ,


启动核心线程 : 如果当前核心线程没有满 , 小于 3 33 个 , 那么创建核心线程执行该任务 ,


启动非核心线程 : 如果当前核心线程已经有 3 33 个 , 但是 非核心线程没有满 , 小于 5 55 个 , 那么会创建非核心线程 , 执行该任务 ;



执行者 Executor 执行任务处理 : 如果核心线程数 有 3 33 个 , 非核心线程数有 5 55 个 , 最大线程数已满 ; 如果用户再提交任务给线程池 , 就会 将任务放入线程池任务队列中排队 ; 如果此时任务队列也满了 , 此时就会 抛出异常 ; 开发者应该通过回调处理被拒绝的任务 ;



线程池从任务队列取出任务并执行 : 线程数量 C CC


线程数量 C < 3 C < 3C<3 : 创建核心线程执行任务 ;

线程数量 3 ≤ C < 8 3 \leq C < 83≤C<8 : 创建非核心线程执行任务 ;


用户调用 Executor 的 execute 执行任务 : 线程数量 C CC


线程数 C = 8 C = 8C=8 , 任务队列没满 : 将任务放入任务队列 ;

线程数 C = 8 C = 8C=8 , 任务队列已满 : 会报出异常 , 使用 Handler 处理错误 ;



 

/**
     * 创建自定义线程池 , 用于并行执行任务 .
     */
    public static final Executor THREAD_POOL_EXECUTOR
            = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
            TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory,
            new ThreadPoolExecutor.DiscardOldestPolicy());
    /**
     * 一个 Executor 执行者 , 以串行顺序 , 一次执行一个任务 ; 针对特定进行 , 该序列化是全局的 , 
     * 即 一个进程只有一个该执行者 . 
     */
    public static final Executor SERIAL_EXECUTOR = Utils.hasHoneycomb() ? new SerialExecutor() :
            Executors.newSingleThreadExecutor(sThreadFactory);
    @TargetApi(11)
    private static class SerialExecutor implements Executor {
        final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
        Runnable mActive;
        public synchronized void execute(final Runnable r) {
            mTasks.offer(new Runnable() {
                public void run() {
                    try {
                        r.run();
                    } finally {
                        scheduleNext();
                    }
                }
            });
            if (mActive == null) {
                scheduleNext();
            }
        }
        protected synchronized void scheduleNext() {
            if ((mActive = mTasks.poll()) != null) {
                THREAD_POOL_EXECUTOR.execute(mActive);
            }
        }
    }



目录
相关文章
|
2月前
|
Java Android开发 UED
🧠Android多线程与异步编程实战!告别卡顿,让应用响应如丝般顺滑!🧵
【7月更文挑战第28天】在Android开发中,确保UI流畅性至关重要。多线程与异步编程技术可将耗时操作移至后台,避免阻塞主线程。我们通常采用`Thread`类、`Handler`与`Looper`、`AsyncTask`及`ExecutorService`等进行多线程编程。
43 2
|
27天前
|
调度 Android开发 开发者
【颠覆传统!】Kotlin协程魔法:解锁Android应用极速体验,带你领略多线程优化的无限魅力!
【8月更文挑战第12天】多线程对现代Android应用至关重要,能显著提升性能与体验。本文探讨Kotlin中的高效多线程实践。首先,理解主线程(UI线程)的角色,避免阻塞它。Kotlin协程作为轻量级线程,简化异步编程。示例展示了如何使用`kotlinx.coroutines`库创建协程,执行后台任务而不影响UI。此外,通过协程与Retrofit结合,实现了网络数据的异步加载,并安全地更新UI。协程不仅提高代码可读性,还能确保程序高效运行,不阻塞主线程,是构建高性能Android应用的关键。
34 4
|
8天前
|
安全 网络安全 数据安全/隐私保护
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享安卓与iOS开发中的线程管理比较
【8月更文挑战第30天】本文将探讨网络安全与信息安全的重要性,并分享关于网络安全漏洞、加密技术和安全意识的知识。我们将了解常见的网络攻击类型和防御策略,以及如何通过加密技术和提高安全意识来保护个人和组织的信息安全。
|
17天前
|
Java 测试技术 Android开发
Android项目架构设计问题之构造一个Android中的线程池如何解决
Android项目架构设计问题之构造一个Android中的线程池如何解决
24 0
|
3天前
|
存储 Android开发 开发者
探索安卓开发之旅:从新手到专家的必经之路
【9月更文挑战第3天】在这篇文章中,我们将踏上一场激动人心的旅程,深入探索安卓开发的广阔天地。无论你是初涉编程世界的新手,还是期望提升技能的开发者,这里都有你需要的知识与技巧。我们将从基础概念讲起,逐步引导你了解安卓应用的核心组件,并分享实用的开发建议。准备好了吗?让我们一起开启这段成长之旅吧!
|
Web App开发 JavaScript 前端开发
Android中WebView加载本地Html,与JavaScript与Android方法相互传值(续)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010046908/article/details/51809558 ...
1027 0
|
8天前
|
供应链 物联网 区块链
未来触手可及:探索新兴技术的趋势与应用安卓开发中的自定义视图:从基础到进阶
【8月更文挑战第30天】随着科技的飞速发展,新兴技术如区块链、物联网和虚拟现实正在重塑我们的世界。本文将深入探讨这些技术的发展趋势和应用场景,带你领略未来的可能性。
|
1天前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义控件
【9月更文挑战第5天】在安卓开发的海洋中,自定义控件如同一艘精致的小船,让开发者能够乘风破浪,创造出既独特又高效的用户界面。本文将带你领略自定义控件的魅力,从基础概念到实战应用,一步步深入理解并掌握这一技术。
|
5天前
|
存储 XML API
安卓应用程序开发:从新手到专家的旅程
【8月更文挑战第33天】在这篇文章中,我们将一起踏上一段激动人心的旅程,探索如何从一个对安卓应用程序开发一无所知的新手,成长为一个能够独立开发复杂应用程序的专家。我们将通过实际案例和代码示例,深入理解安卓开发的各个方面,包括用户界面设计、数据存储、网络通信等。无论你是刚刚入门,还是已经有一些基础,这篇文章都将为你提供宝贵的知识和技能,帮助你在安卓开发的道路上更进一步。
|
2天前
|
XML Java Android开发
探索Android开发之旅:打造你的第一个应用
【9月更文挑战第4天】在这篇专为初学者设计的文章中,我们将一起踏上激动人心的Android开发之旅。从设置开发环境到实现一个简单的“Hello World”应用,每一步都充满了发现和学习。文章将引导你理解Android开发的基础知识,并鼓励你动手实践。让我们开始吧,创造你的第一款Android应用,开启技术世界的新篇章!