Creating a Manager for Multiple Threads

1.You should also read

  The previous lesson showed how to define a task that executes on a separate thread. If you only want to run the task once, this may be all you need. If you want to run a task repeatedly on different sets of data, but you only need one execution running at a time, an IntentService suits your needs. To automatically run tasks as resources become available, or to allow multiple tasks to run at the same time (or both), you need to provide a managed collection of threads. To do this, use an instance of ThreadPoolExecutor, which runs a task from a queue when a thread in its pool becomes free. To run a task, all you have to do is add it to the queue.

 ThreadPoolExecutor 类用来管理线程池。

  A thread pool can run multiple parallel instances of a task, so you should ensure that your code is thread-safe. Enclose variables that can be accessed by more than one thread in asynchronized block. This approach will prevent one thread from reading the variable while another is writing to it. Typically, this situation arises with static variables, but it also occurs in any object that is only instantiated once. To learn more about this, read the Processes and Threads API guide.

 多线程时,要注意同步问题。本文示例演示多线程访问一个静态变量。

2.Define the Thread Pool Class 定义一个线程池管理类

  Instantiate ThreadPoolExecutor in its own class. Within this class, do the following:

Use static variables for thread pools
  You may only want a single instance of a thread pool for your app, in order to have a single control point for restricted CPU or network resources. If you have different Runnable types, you may want to have a thread pool for each one, but each of these can be a single instance. For example, you can add this as part of your global field declarations:
 public class PhotoManager {
...
static {
...
// Creates a single static instance of PhotoManager
sInstance = new PhotoManager();
}
...
Use a private constructor
  Making the constructor private ensures that it is a singleton, which means that you don't have to enclose accesses to the class in a synchronized block:
 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() {
...
}
Start your tasks by calling methods in the thread pool class.
  Define a method in the thread pool class that adds a task to a thread pool's queue. For example:
 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());
...
}
Instantiate a Handler in the constructor and attach it to your app's UI thread.
  A Handler allows your app to safely call the methods of UI objects such as View objects. Most UI objects may only be safely altered from the UI thread. This approach is described in more detail in the lesson Communicate with the UI Thread. For example:
 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) {
...
}
...
}
}

3.Determine the Thread Pool Parameters 线程管理类的几个重要成员

  Once you have the overall class structure, you can start defining the thread pool. To instantiate a ThreadPoolExecutor object, you need the following values:

  • Initial pool size and maximum pool size 线程池的大小
   The initial number of threads to allocate to the pool, and the maximum allowable number. The number of threads you can have in a thread pool depends primarily on the number of cores available for your device. This number is available from the system environment:
 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();
}
  通常是cpu的核心数,但 availableProcessors() 并不一定是实际cpu核数目,要看具体实现。有可能实际小。
   This number may not reflect the number of physical cores in the device; some devices have CPUs that deactivate one or more cores depending on the system load. For these devices,availableProcessors() returns the number of active cores, which may be less than the total number of cores.
  • Keep alive time and time unit 线程的活跃时间

   The duration that a thread will remain idle before it shuts down. The duration is interpreted by the time unit value, one of the constants defined in TimeUnit.

  • A queue of tasks 异步任务队列

   The incoming queue from which ThreadPoolExecutor takes Runnable objects. To start code on a thread, a thread pool manager takes a Runnable object from a first-in, first-out queue and attaches it to the thread. You provide this queue object when you create the thread pool, using any queue class that implements the BlockingQueue interface. To match the requirements of your app, you can choose from the available queue implementations; to learn more about them, see the class overview for ThreadPoolExecutor. This example uses the LinkedBlockingQueue class:

 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>();
...
}
...
}

4.Create a Pool of Threads 创建ThreadPoolExecutor实例

  To create a pool of threads, instantiate a thread pool manager by calling ThreadPoolExecutor(). This creates and manages a constrained group of threads.   Because the initial pool size and the maximum pool size are the same, ThreadPoolExecutor creates all of the thread objects when it is instantiated. For example:

   private PhotoManager() {
...
// Sets the amount of time an idle thread waits before terminating
private static final int KEEP_ALIVE_TIME = ;
// 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);
}
 

Android 性能优化(16)线程优化:Creating a Manager for Multiple Threads 如何创建一个线程池管理类的更多相关文章

  1. 创建一个实例&创建一个线程。。

    using System; using System.Threading; namespace WorkerThread02 { class ThreadTest { bool done; stati ...

  2. python创建一个线程和一个线程池

    创建一个线程 1.示例代码 import time import threading def task(arg): time.sleep(2) while True: num = input('> ...

  3. Creating a Manager for Multiple Threads_翻译

    The previous lesson showed how to define a task that executes on a separate thread. If you only want ...

  4. QT 创建一个线程播放监控视频

    1.创建一个线程类(PlayVideoThread): PlayVideoThread.h头文件 #pragma once #include <QObject> #include &quo ...

  5. [转]使用VC/MFC创建一个线程池

    许多应用程序创建的线程花费了大量时间在睡眠状态来等待事件的发生.还有一些线程进入睡眠状态后定期被唤醒以轮询工作方式来改变或者更新状态信息.线程池可以让你更有效地使用线程,它为你的应用程序提供一个由系统 ...

  6. java多线程学习(两)——创建一个线程

    一个.java创建两个线程的方法 1.从java.lang.Thread派生一个新类线程类,其覆盖run()方法 2.实现Runnable接口.重载Runnable接口中的run()方法. 使用Thr ...

  7. ThreadPoolExecutor – Java Thread Pool Example(如何使用Executor框架创建一个线程池)

    Java thread pool manages the pool of worker threads, it contains a queue that keeps tasks waiting to ...

  8. 创建一个线程池(java)

    private ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("billService-poo ...

  9. 如何创建一个线程安全的Map?

    1,使用普通的旧的Hashtable HashMap允许null作为key,而Hashtable不可以 2,使用Collections中同步化的包装方法synchronizedMap 3,使用conc ...

随机推荐

  1. memcache 原理 & 监测 & 查看状态 & stats & 结构

    Mencache内存存储方式:slab/LRU,采用预先申请固定大小的内存页(slab/page),然后再把内存分成多个块(chunk) 先放一张从网上找到的memcache内存结构图,觉得非常的赞:

  2. hdu - 3549 Flow Problem (最大流模板题)

    http://acm.hdu.edu.cn/showproblem.php?pid=3549 Ford-Fulkerson算法. #include <iostream> #include ...

  3. HDU 5641 King's Phone【模拟】

    题意: 给定一串密码, 判断是否合法. 长度不小于4 不能重复经过任何点 不能跳过中间点,除非中间点已经经过一次. 分析: 3*3直接记录出可能出现在两点之间的点,直接模拟就好. 注意审题,别漏了判断 ...

  4. vuex 存值 及 取值 的操作

    1.传值 // 定义参数 let params = { workItemId: workItemId, flowInstId: flowInstId, itemStatus: itemStatus, ...

  5. Android 5.1 Settings源代码简要分析

    转载请注明出处,谢谢~http://blog.csdn.net/u011974987/article/details/51004854. 概述: 先声明:本人工作快两年了,仍是菜鸟级别的.羞愧啊!曾经 ...

  6. chrome.socket

    chrome.socket https://chajian.baidu.com/developer/apps/socket.html#method-create 描述: 使用 chrome.socke ...

  7. Linux查看文件最后几行的命令

    tail -n 20 filename说明:显示filename最后20行

  8. DBCP,C3P0,Tomcat_JDBC 性能及稳定性測试

    原创文章,转载请指明出处:http://aub.iteye.com/blog/1404219, 尊重他人即尊重自己 DBCP,C3P0,Tomcat_JDBC 性能及稳定性測试 1.測试环境: 硬件环 ...

  9. 容器HashMap原理(学习)

    一.概述 基于哈希表的 Map 接口的非同步实现,允许使用 null 值和 null 键,不保证映射的顺序 二.数据结构 HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体:Has ...

  10. 利用JFreeChart生成组合图表 (8) (转自 JSP开发技术大全)

    利用JFreeChart生成组合图表 (8) (转自 JSP开发技术大全) 14.8 利用JFreeChart生成组合图表  实例位置:光盘\mingrisoft\14\dxyy\02 通过JFree ...