GlobalThreadPools.java:

/**

* 全局使用的线程池

*/

public class GlobalThreadPools {

private static String TAG = GlobalThreadPools.class.getSimpleName();

private static ExecutorService THREAD_POOL_EXECUTOR;//线程池

private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();//CPU数量

private static final int CORE_POOL_SIZE = CPU_COUNT;//核心线程数

private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2;//最大线程数

private static final int KEEP_ALIVE_SECONDS = 60;//线程闲置后的存活时间

private static final BlockingQueue sPoolWorkQueue = new LinkedBlockingQueue<>(CPU_COUNT);//任务队列

private static final ThreadFactory sThreadFactory = new ThreadFactory() {//线程工厂

private final AtomicInteger mCount = new AtomicInteger(1);

public Thread newThread(Runnable r) {

return new Thread(r, "MangoTask #" + mCount.getAndIncrement());

}

};

//初始化线程池

private void initThreadPool() {

THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(

CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,

sPoolWorkQueue, sThreadFactory, new RejectedHandler()){

@Override

public void execute(Runnable command) {

super.execute(command);

Log.e(TAG,"ActiveCount="+getActiveCount());

Log.e(TAG,"PoolSize="+getPoolSize());

Log.e(TAG,"Queue="+getQueue().size());

}

};

}

private static class RejectedHandler implements RejectedExecutionHandler {

@Override

public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {

//可在这里做一些提示用户的操作

// Log.v("+++","is over the max task...");

}

}

private static GlobalThreadPools instance;

private GlobalThreadPools(){

initThreadPool();

}

public static GlobalThreadPools getInstance(){

if (instance == null) {

instance = new GlobalThreadPools();

}

return instance;

}

public void execute(Runnable command){

THREAD_POOL_EXECUTOR.execute(command);

}

// /**

// * 通过interrupt方法尝试停止正在执行的任务,但是不保证真的终止正在执行的任务

// * 停止队列中处于等待的任务的执行

// * 不再接收新的任务

// * @return 等待执行的任务列表

// */

// public List shutdownNow(){

// return THREAD_POOL_EXECUTOR.shutdownNow();

// }

//

// /**

// * 停止队列中处于等待的任务

// * 不再接收新的任务

// * 已经执行的任务会继续执行

// * 如果任务已经执行完了没有必要再调用这个方法

// */

// public void shutDown(){

// THREAD_POOL_EXECUTOR.shutdown();

// sPoolWorkQueue.clear();

// }

}

调用:

//线程池开启任务

GlobalThreadPools.getInstance().execute(new Runnable() {

@Override

public void run() {

.......

}

});

线程池

线程池概念来源于Java中的Executor,它是一个接口,真正的实现为ThreadPoolExecutor。ThreadPoolExecutor提供了一系列参数来配置线程池。

优点

1:重用线程池中的线程,线程在执行完任务后不会立刻销毁,而会等待另外的任务,这样就不会频繁地创建、销毁线程和调用GC。。

2:有效控制线程池的最大并发数,避免大量线程抢占资源出现的问题。

3:对多个线程进行统一地管理,可提供定时执行及指定间隔循环执行的功能。

ThreadPoolExecutor 有多个重载方法,但最终都调用了这个构造方法

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue,

ThreadFactory threadFactory,

RejectedExecutionHandler handler)

参数:

corePoolSize:线程池中核心线程的数量;为了内存优化,在线程池维护了几个重要的线程,不达到一定条件不开辟其余线程

maximumPoolSize :线程池中最大线程数量:这个数量是包括核心线程的,当线程池中的正在执行的线程池达到了这个数字,再提交线程如果你不做特殊处理将会抛出异常

keepAliveTime:非核心线程的超时时长;当线程池中的非核心线程闲置时间超过这个值代表的时间后,将会被回收;同时如果调用ThreadPoolExecutor.allowCoreThreadTimeOut(true),那么核心线程也会符合这个设置

unit:keepAliveTime值的单位,可以是时分秒等

workQueue:存放待执行的线程;你通过execute方法提交线程,但是这些线程还没达到执行条件,那么就会保存在这个队列里

threadFactory:创建线程池的工厂;在这个工厂里,我们可以指定线程的一些信息

handler:线程提交拒绝策略;通常是线程池中的正在执行的线程数量已经达到了最大线程数或线程池关闭,如果不传,默认是抛出一个RejectedExecutionException,所以最好传下

推荐使用 Executors 的工厂方法来创建线程池,通过直接或间接的配置 ThreadPoolExecutor 的参数来构建线程池,常用的线程池有如下 4 种,newFixedThreadPool ,newCachedThreadPool,

newScheduledThreadPool 和 newSingleThreadExecutor。

FixedThreadPool 只有核心线程,并且数量是固定的,也不会被回收,能更快地响应外界请求。

SingleThreadPool 只有一个核心线程,确保所有任务都在同一线程中按顺序完成。因此不需要处理线程同步的问题。

CachedThreadPool 只有非核心线程,最大线程数非常大,所有线程都活动时,会为新任务创建新线程,否则利用空闲线程处理任务,任何任务都会被立即执行。

ScheduledThreadPool 核心线程数固定,非核心线程数没有限制,主要用于执行定时任务以及有固定周期的重复任务。

ThreadPoolExecutor 执行任务时大致遵循如下流程:

1.如果线程池中的线程数未达到核心线程数,则会立马启用一个核心线程去执行。

2.如果线程池中的线程数已经达到核心线程数,且任务队列workQueue未满,则将新线程放入workQueue中等待执行。

3.如果线程池中的线程数已经达到核心线程数但未超过线程池规定最大值,且workQueue已满,则开启一个非核心线程来执行任务。

4.如果线程池中的线程数已经超过线程池规定最大值,则拒绝执行该任务,采取饱和策略,并抛出RejectedExecutionException异常。

线程池大小:(N为CPU数量)

如果是CPU密集型应用,则线程池大小设置为N+1

如果是IO密集型应用,则线程池大小设置为2N+1

I/O密集型

指的是系统的CPU效能相对硬盘/内存的效能要好,大部分的状况是 CPU 在等 I/O (硬盘/内存) 的读/写, CPU Loading 不高。

CPU密集型

指的是系统的 硬盘/内存 效能 相对 CPU 的效能 要好,大部分的状况是 CPU Loading 100%,CPU 要读/写 I/O (硬盘/内存),I/O在很短的时间就可以完成,而 CPU 还有许多运算要处理,CPU Loading 很高。

获取CPU数量的方法为:

Runtime.getRuntime().availableProcessors();

android 多线程封装,Android 线程池的封装相关推荐

  1. Android AsyncTask两种线程池分析和总结

    转自:http://bbs.51cto.com/thread-1114378-1-1.html Android AsyncTask两种线程池分析和总结 (一)    前言 在android Async ...

  2. Java多线程系列--“JUC线程池”06之 Callable和Future

    转载自  Java多线程系列--"JUC线程池"06之 Callable和Future Callable 和 Future 简介 Callable 和 Future 是比较有趣的一 ...

  3. linux下c语言线程传参数,【linux】C语言多线程中运行线程池,在线程池中运行线程池,,传递的结构体参数值为空/NULL/0...

    C语言多线程中运行线程池,在线程池中运行线程池,,传递的结构体参数值为空/NULL/0 本贴问题,之前已经提问过一次,当时已经解决了,原贴在这里https://segmentfault.com/q/1 ...

  4. Android复习06【网络编程提高篇-安装GsonFormat、HttpUrlConnection封装、线程池、GsonFormat解析Json、自动加载下一页、自定义组件、页头页尾刷新、侧滑删除】

    2020-04-07 星期二 [第8周] [考试不考...] 目   录 思维导图 安装GsonFormat插件 添加网络访问权限 GitHub---HttpUrlConnection封装 线程池 G ...

  5. Android 面试题目之 线程池

    [color=red][size=xx-large]记不住密码怎么办?[/size][/color] [url]http://a.app.qq.com/o/simple.jsp?pkgname=com ...

  6. android AsyncTask 只能在线程池里单个运行的问题

    android 的AysncTask直接调用Execute会在在一个线程池里按调用的先后顺序依次执行. 如果应用的所有网络获取都依赖这个来做,当有一个网络请求柱塞,就导致其它请求也柱塞了. 在3.0 ...

  7. Android开发中的线程池使用

    一.前言 既然Android中已经有了线程的概念,那么为什么需要使用线程池呢?我们从两个方面给出使用线程池的原因. 首先线程的新建和销毁都是存在性能上的消耗的,如果一个时间段有大量的网络请求,那么就需 ...

  8. 线程池的封装和使用(代理模式工厂模式)

    通过线程池代理类和线程池工厂完成对线程池操作的解耦. 简单的代理模式和简单的工厂模式 1.创建一个代理类 public class ThreadPoolProxy {ThreadPoolExecuto ...

  9. 线程池,封装使用,实现控制子线程

    类代码   using System; using System.Collections.Generic; using System.Text; using System.Threading; nam ...

最新文章

  1. 创建新的apple id_Google是新的Apple吗?
  2. odbc 函数序列错误_python时间序列:移动窗口函数前篇
  3. 无意中发现了一位清华大佬的代码模版
  4. stm32官方例程在哪找_正点原子Linux第十一章模仿STM32驱动开发格式实验
  5. 唯一分解定理(算术基本定理)详解——hdu5248和lightoj1341
  6. Java-进阶:多线程2
  7. B1922 [Sdoi2010]大陆争霸 最短路
  8. [完结]以C++与Java为例,详解数据结构的动态增长策略
  9. python csv模块用法_python使用csv模块如何将数据存放在一张表的不同行?
  10. 独家 | Face++印奇:AI是场持久战,但第一阶段明年结束
  11. [Xcode 实际操作]五、使用表格-(8)自定义UITableView单元格Accessory样式(附件图标)
  12. torch.FloatTensor和torch.Tensor、torch.tensor
  13. 将luarocks整合进openresty,并安装lfs
  14. windows操作快捷键
  15. DNT精英论坛(暨.NET北京俱乐部)第3期沙龙:区块链跨链技术的设计与实践
  16. 从输入URL到页面加载的过程?由一道题完善自己的前端知识体系!
  17. 删除主键索引 oracle,删除主键无法删除对应索引问题 drop constraint
  18. 2023 年 IEEE Fellow 名单公布!唐立新、姬水旺、宗成庆、朱军、宋厚冰等入选
  19. ob2222mcp非隔离电源芯片
  20. 【janus 】openresty +janus

热门文章

  1. 【Elasticsearch】 elasticsearch中 rollover 的用法
  2. 【Flink】flink-1.12 通过 -t 指定模式后无法指定yarn参数
  3. 【ElasticSearch】Es 源码之 NodeConnectionsService 源码解读
  4. 【SpringCloud】was unable to refresh its cache! status = Cannot execute request on any known server
  5. 【clickhouse】clickhouse 一些博客链接
  6. 【Linux】Linux测试磁盘 IO 性能
  7. 数据结构知识点大汇总(八)
  8. redis+mysql几种用法
  9. linux套接字端口,多端口监听套接字linux(multiport listening socket linux)
  10. SQL中 left join 左表合并去重实用技巧