Android官方开发文档Training系列课程中文版:线程执行操作之创建多线程管理器

简介: 原文地址:http://android.xsoftlab.net/training/multiple-threads/create-threadpool.html上节课我们学习了如何定义一个任务。

原文地址:http://android.xsoftlab.net/training/multiple-threads/create-threadpool.html

上节课我们学习了如何定义一个任务。如果只是执行单次任务,那么刚刚所学的已经基本满足要求了。如果需要针对不同的数据执行同种任务,并且需要同一时间只能执行一项任务,那么IntentService可能会适合你。如果要使任务随着资源的可用而执行,或者同一时间需要运行多个任务,那么就需要专门管理这些线程了。Android系统为此提供了一个类,那就是传说中的ThreadPoolExecutor。它可以在线程可用时自动运行队列中的任务。如果要运行一个任务,只需要将任务添加到队列中即可。

ThreadPoolExecutor允许多个线程同时进行,所以应当确保代码是线程安全的。要确保可能会被多个线程访问到的变量被放在同步代码块中。这种方法可以防止一个线程正在读取一个变量的值,而另一个变量正在对这个变量写入新值的现象出现。通常情况下,这种现象会发生在静态变量中,但是也会发生在单例对象上。

定义线程池类

在该类内实例化一个ThreadPoolExecutor对象,并在该类内执行以下工作:

  • 对线程池对象使用静态变量引用

    在APP内通常只需要一个线程池对象的存在:为了对CPU资源或网络资源有一个单一的控制。如果含有不同的Runnable类型,你可能希望对每种类型都创建一个单独线程池,但是每种类型都还是单例类型。在这里的例子中,可以添加以下代码作为全局属性声明。

    public class PhotoManager {
        ...
        static  {
            ...
            // Creates a single static instance of PhotoManager
            sInstance = new PhotoManager();
        }
        ...
  • 使用私有构造方法:
    私有的构造方法可以确保该类只有一个对象存在。

public class PhotoManager {
    ...
    /**
     * Constructs the work queues and thread pools used to download
     * and decode images. Because the constructor is marked private,
     * it's unavailable to other classes, even in the same package.
     */
    private PhotoManager() {
    ...
    }
  • 调用线程池的相关方法启动任务:
    在线程池类内定义一个可以向线程池队列中添加任务的方法。

    public class PhotoManager {
    ...
    // Called by the PhotoView to get a photo
    static public PhotoTask startDownload(
        PhotoView imageView,
        boolean cacheFlag) {
        ...
        // Adds a download task to the thread pool for execution
        sInstance.
                mDownloadThreadPool.
                execute(downloadTask.getHTTPDownloadRunnable());
        ...
    }
  • 在构造方法中实例化一个Handler对象,并将其连接到UI线程:Handler允许安全的调用比如View这种UI对象。大多数的UI对象只允许被UI线程访问。

     private PhotoManager() {
    ...
        // Defines a Handler object that's attached to the UI thread
        mHandler = new Handler(Looper.getMainLooper()) {
            /*
             * handleMessage() defines the operations to perform when
             * the Handler receives a new Message to process.
             */
            @Override
            public void handleMessage(Message inputMessage) {
                ...
            }
        ...
        }
    }

确定线程池参数

如果要实例化ThreadPoolExecutor对象,需要用到以下值:

线程池的初始值以及最大值:

  • 线程数量的初始值用于指定池子的初始大小,最大值代表了该线程池所允许开放的最大并发数量。线程池中的线程数量取决于设备的可用核心数。这个值与当前的设备颇有关系:
public class PhotoManager {
...
    /*
     * Gets the number of available cores
     * (not always the same as the maximum number of cores)
     */
    private static int NUMBER_OF_CORES =
            Runtime.getRuntime().availableProcessors();
}

这个值可能不能够反映设备的物理核心数量;在一些设备上,核心是否可用取决于系统是否加载。对于这些设备,availableProcessors()返回了当前的活跃核心数量,这个值可能要比真实的总核心数要低。

存活时长及单位

  • 线程在被关闭之间的闲置时长。这个时长由时间单元值负责解释,这些时间单位常量被定义在类TimeUnit中。

任务队列

  • 一个持有Runnable对象的队列。为了启动线程中的执行代码,线程池管理器采用了先进先出的管理原则。在创建线程池之前需要提供一个这样的队列,使用任何实现了BlockingQueue接口的类皆可。为了匹配到APP的要求,你可以选择适当的队列实现;学习更多它们的相关知识,请参见ThreadPoolExecutor的描述文档。这里的使用了LinkedBlockingQueue:
 public class PhotoManager {
    ...
    private PhotoManager() {
        ...
        // A queue of Runnables
        private final BlockingQueue<Runnable> mDecodeWorkQueue;
        ...
        // Instantiates the queue of Runnables as a LinkedBlockingQueue
        mDecodeWorkQueue = new LinkedBlockingQueue<Runnable>();
        ...
    }
    ...
}

线程池创建

创建一个线程池,只需调用ThreadPoolExecutor()实例化一个线程池管理器就好。它会创建并管理一组线程。因为线程池大小的初始值与最大值是相同的,所以ThreadPoolExecutor()会在初始化的时候创建出所指定的线程数量:

    private PhotoManager() {
        ...
        // Sets the amount of time an idle thread waits before terminating
        private static final int KEEP_ALIVE_TIME = 1;
        // Sets the Time Unit to seconds
        private static final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
        // Creates a thread pool manager
        mDecodeThreadPool = new ThreadPoolExecutor(
                NUMBER_OF_CORES,       // Initial pool size
                NUMBER_OF_CORES,       // Max pool size
                KEEP_ALIVE_TIME,
                KEEP_ALIVE_TIME_UNIT,
                mDecodeWorkQueue);
    }
目录
相关文章
|
11月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1882 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
11月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1206 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
11月前
|
移动开发 Rust JavaScript
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1262 4
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
11月前
|
移动开发 Android开发
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
507 0
|
12月前
|
开发工具 Android开发
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
1022 11
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
|
Java 开发工具 Maven
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
1469 6
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
6375 77
|
安全 数据库 Android开发
在Android开发中实现两个Intent跳转及数据交换的方法
总结上述内容,在Android开发中,Intent不仅是活动跳转的桥梁,也是两个活动之间进行数据交换的媒介。运用Intent传递数据时需注意数据类型、传输大小限制以及安全性问题的处理,以确保应用的健壯性和安全性。
761 11
|
移动开发 Java 编译器
Kotlin与Jetpack Compose:Android开发生态的演进与架构思考
本文从资深Android工程师视角深入分析Kotlin与Jetpack Compose在Android系统中的技术定位。Kotlin通过空安全、协程等特性解决了Java在移动开发中的痛点,成为Android官方首选语言。Jetpack Compose则引入声明式UI范式,通过重组机制实现高效UI更新。两者结合不仅提升开发效率,更为跨平台战略和现代架构模式提供技术基础,代表了Android开发生态的根本性演进。
639 0
|
安全 Java Android开发
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
561 0
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡

热门文章

最新文章