本篇主要介绍Android自带的线程池的管理。

包含开始任务、重新加载、添加删除任务等,示例代码如下:

 package com.jiao.threadpooltest;

 import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ProgressBar;
import android.widget.Toast; /**
* @TODO [线程池控制 ]
*/
public class MyRunnableActivity extends Activity implements OnClickListener { /** 任务执行队列 */
private ConcurrentLinkedQueue<MyRunnable> taskQueue = null;
/**
* 正在等待执行或已经完成的任务队列
*
* 备注:Future类,一个用于存储异步任务执行的结果,比如:判断是否取消、是否可以取消、
* 是否正在执行、是否已经完成等
*
* */
private ConcurrentMap<Future, MyRunnable> taskMap = null; /**
* 创建一个不限制大小的线程池 此类主要有以下好处 1,以共享的无界队列方式来运行这些线程.
* 2,执行效率高。 3,在任意点,在大多数nThreads 线程会处于处理任务的活动状态
* 4,如果在关闭前的执行期间由于失败而导致任何线程终止,那么一个新线程将代替它执行后续的任务(如果需要)。
*
* */
private ExecutorService mES = null;
/**
* 在此类中使用同步锁时使用如下lock对象即可,官方推荐的,不推荐直接使用MyRunnableActivity.this类型的,可以详细读一下/
* framework/app下面的随便一个项目
*/
private Object lock = new Object(); /** 唤醒标志,是否唤醒线程池工作 */
private boolean isNotify = true; /** 线程池是否处于运行状态(即:是否被释放!) */
private boolean isRuning = true; /** 任务进度 */
private ProgressBar pb = null; /** 用此Handler来更新我们的UI */
private Handler mHandler = null;
/**
* Overriding methods
*
* @param savedInstanceState
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_runnable_main);
init();
} public void init() {
pb = (ProgressBar) findViewById(R.id.progressBar1);
findViewById(R.id.button1).setOnClickListener(this);
findViewById(R.id.button2).setOnClickListener(this);
findViewById(R.id.button3).setOnClickListener(this);
findViewById(R.id.button4).setOnClickListener(this);
findViewById(R.id.button5).setOnClickListener(this);
taskQueue = new ConcurrentLinkedQueue<MyRunnable>();
taskMap = new ConcurrentHashMap<Future, MyRunnable>();
if (mES == null) {
// 创建一个线程池
mES = Executors.newCachedThreadPool();
} // 用于更新ProgressBar进度条
mHandler = new Handler() {
/**
* Overriding methods
*
* @param msg
*/
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
pb.setProgress(msg.what);
} }; } /**
* Overriding methods
*
* @param v
*/
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:// 开始任务
start();
break;
case R.id.button2:// 取消任务
stop();
break;
case R.id.button3:// 重新加载
reload(new MyRunnable(mHandler));
break;
case R.id.button4:// 释放资源
release();
break;
case R.id.button5:// 添加任务
addTask(new MyRunnable(mHandler));
break; default:
break;
}
} /**
* <Summary Description>
*/
private void addTask(final MyRunnable mr) { mHandler.sendEmptyMessage(0); if (mES == null) {
mES = Executors.newCachedThreadPool();
notifyWork();
} if (taskQueue == null) {
taskQueue = new ConcurrentLinkedQueue<MyRunnable>();
} if (taskMap == null) {
taskMap = new ConcurrentHashMap<Future, MyRunnable>();
} mES.execute(new Runnable() { @Override
public void run() {
/**
* 插入一个Runnable到任务队列中
* 这个地方解释一下,offer跟add方法,试了下,效果都一样,没区别,官方的解释如下: 1 offer : Inserts
* the specified element at the tail of this queue. As the queue
* is unbounded, this method will never return {@code false}. 2
* add: Inserts the specified element at the tail of this queue.
* As the queue is unbounded, this method will never throw
* {@link IllegalStateException} or return {@code false}.
*
*
* */
taskQueue.offer(mr);
// taskQueue.add(mr);
notifyWork();
}
}); Toast.makeText(MyRunnableActivity.this, "已添加一个新任务到线程池中 !", 0).show();
} /**
* <Summary Description>
*/
private void release() {
Toast.makeText(MyRunnableActivity.this, "释放所有占用的资源!", 0).show(); /** 将ProgressBar进度置为0 */
mHandler.sendEmptyMessage(0);
isRuning = false; Iterator iter = taskMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<Future, MyRunnable> entry = (Map.Entry<Future, MyRunnable>) iter
.next();
Future result = entry.getKey();
if (result == null) {
continue;
}
result.cancel(true);
taskMap.remove(result);
}
if (null != mES) {
mES.shutdown();
} mES = null;
taskMap = null;
taskQueue = null; } /**
* 重新加载
*/
private void reload(final MyRunnable mr) {
mHandler.sendEmptyMessage(0);//重置进度条
if (mES == null) {
mES = Executors.newCachedThreadPool();
notifyWork();
} if (taskQueue == null) {
taskQueue = new ConcurrentLinkedQueue<MyRunnable>();
} if (taskMap == null) {
taskMap = new ConcurrentHashMap<Future, MyRunnable>();
} mES.execute(new Runnable() { @Override
public void run() {
/** 插入一个Runnable到任务队列中 */
taskQueue.offer(mr);
// taskQueue.add(mr);
notifyWork();
}
}); mES.execute(new Runnable() {
@Override
public void run() {
if (isRuning) {
MyRunnable myRunnable = null;
synchronized (lock) {
myRunnable = taskQueue.poll(); // 从线程队列中取出一个Runnable对象来执行,如果此队列为空,则调用poll()方法会返回null
if (myRunnable == null) {
isNotify = true;
}
} if (myRunnable != null) {
taskMap.put(mES.submit(myRunnable), myRunnable);
}
}
}
});
} /**
* <Summary Description>
*/
private void stop() { Toast.makeText(MyRunnableActivity.this, "任务已被取消!", 0).show(); for (MyRunnable runnable : taskMap.values()) {
runnable.setCancleTaskUnit(true);
}
} /**
* <Summary Description>
*/
private void start() { if (mES == null || taskQueue == null || taskMap == null) {
Log.i("KKK", "某资源是不是已经被释放了?");
return;
}
mES.execute(new Runnable() {
@Override
public void run() {
if (isRuning) {
MyRunnable myRunnable = null;
synchronized (lock) {
myRunnable = taskQueue.poll(); // 从线程队列中取出一个Runnable对象来执行,如果此队列为空,则调用poll()方法会返回null
if (myRunnable == null) {
isNotify = true;
// try
// {
// myRunnable.wait(500);
// }
// catch (InterruptedException e)
// {
// e.printStackTrace();
// }
}
} if (myRunnable != null) {
taskMap.put(mES.submit(myRunnable), myRunnable);
}
} }
});
} private void notifyWork() {
synchronized (lock) {
if (isNotify) {
lock.notifyAll();
isNotify = !isNotify;
}
}
}
}

Android线程池(二)的更多相关文章

  1. Android线程池(二)——ThreadPoolExecutor及其拒绝策略RejectedExecutionHandler使用演示样例

    MainActivity例如以下: package cc.vv; import java.util.concurrent.LinkedBlockingQueue; import java.util.c ...

  2. Android 线程池概念及使用

    一:使用线程池的原因 在android开发中经常会使用多线程异步来处理相关任务,而如果用传统的newThread来创建一个子线程进行处理,会造成一些严重的问题: 在任务众多的情况下,系统要为每一个任务 ...

  3. Android(java)学习笔记267:Android线程池形态

    1. 线程池简介  多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.     假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...

  4. android线程池ThreadPoolExecutor的理解

    android线程池ThreadPoolExecutor的理解 线程池 我自己理解看来.线程池顾名思义就是一个容器的意思,容纳的就是ThreadorRunable, 注意:每一个线程都是需要CPU分配 ...

  5. android 线程池的使用

    转自http://www.trinea.cn/android/java-android-thread-pool/ Java(Android)线程池 介绍new Thread的弊端及Java四种线程池的 ...

  6. Android(java)学习笔记211:Android线程池形态

    1. 线程池简介  多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.     假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...

  7. 最强大的Android线程池框架

    背景 大家都知道在我们的开发中永远都离不开多线程,对于我们为什么要使用多线程,多线程的使用和多线程的一些基础知识这里我们就不讲了,有兴趣的朋友可以去看一下博主之前的几篇文章: 线程你真的了解它吗 这才 ...

  8. Android线程池使用终结版

    有一段时间没写博文了,今天抽空总结一下,也希望能通过自己写的这些文章,加深理解的同时能帮 助在技术方面有疑点的朋友搞清楚个所以然来,由于经常会在网上或群里看到有朋友会问线程方面的 东西,就像我一个朋友 ...

  9. -Android -线程池 批量上传图片 -附php接收代码

    (出处:http://www.cnblogs.com/linguanh/) 目录: 1,前序 2,类特点 3,用法 4,java代码 5,php代码 1,前序 还是源于重构,看着之前为赶时间写着的碎片 ...

随机推荐

  1. Errors running builder 'JavaScript Validator' on project

    builders去掉JavaScript Validator. 如图: 参考文献: [1]http://www.cnblogs.com/enshrineZither/p/4062248.html

  2. iOS-appStore发布流程

    appStore上传苹果应用程序软件发布流程http://blog.sina.com.cn/s/blog_68661bd801019uzd.html

  3. PEP8 Python 编码规范

    一 代码编排1 缩进.4个空格的缩进(编辑器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格.2 每行最大长度79,换行可以使用反斜杠,最好使用圆括号.换行点要在操作符的后边敲回车.3 类 ...

  4. 使用自带的JavaScriptSerializer序列化实体 指定的属性如何不序列化

    public class GridConfig { public string width = "100%"; public string source = "dataA ...

  5. 仿照微信的效果,实现了一个支持多选、选原图和视频的图片选择器,适配了iOS6-9系统,3行代码即可集成.

    提示:如果你发现了Bug,请尝试更新到最新版.目前最新版是1.6.4,此前的版本或多或少存在一些bug的~如果你已经是最新版了,请留一条评论,我看到了会尽快处理和修复哈~ 关于升级iOS10和Xcdo ...

  6. JS数组追加数组采用push.apply的坑

    JS数组追加数组没有现成的函数,这么多年我已经习惯了a.push.apply(a, b);这种自以为很酷的,不需要写for循环的写法,一直也没遇到什么问题,直到今天我要append的b是个很大的数组时 ...

  7. Linq专题之查询操作

    前面我们主要讲解的是Linq的查询表达式,Linq不但提供了一些基本的查询表达式,还提供了数十个查询操作.比如筛选操作.聚合操作.投影操作等等.通过这些查询操作可以更方便的对数据源进行处理. Linq ...

  8. C#调用webservice 时如何传递实体对象

    在webservice端公开一个实体类,然后实例化,赋值,然后再给到webservice,可以实现,但是,即使调用端和service端的实体类完全一致,你也要重新实例化service端的,重新赋值,将 ...

  9. Python入门笔记(26):Python执行环境

    一.python特定的执行环境 在当前脚本继续进行 创建和管理子进程 执行外部命令或程序 执行需要输入的命令 通过网络来调用命令 执行命令来创建需要处理的输出 动态生成Python语句 导入Pytho ...

  10. 基于吉日嘎底层架构的Web端权限管理操作演示-角色管理

    上一篇介绍了用户管理,这篇来介绍角色管理,这是权限管理的核心部分,因为我们的权限管理系统是基于角色的,有个高大上的英文名叫RBAC(Role Based Acccess Control). 下面的这段 ...