本篇主要介绍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. JavaScript TDD with Mocha

    开发现状 当新的版本快要发布的时候,大家都忙于加班,加紧修复BUG1.BUG2.我想这就是很多公司开发的现状. 为了不至于让上线的版本挂掉挂掉,少不了就是 人肉测试. 在一个项目中,我们会做许许多多各 ...

  2. python面试题大全(二)

    转载请注明出处http://www.cnblogs.com/goodhacker/p/3387027.html 1.python中类方法.类实例方法.静态方法有何区别? 区别: 类方法和静态方法都可以 ...

  3. 美了美了!22款精美的 iOS 应用程序图标模板

    22款制作精美的 iOS 应用程序图标设计作品,遵循图形设计的现代潮流,所有图标都非常了不起,给人惊喜.通过学习这些移动应用程序图标,设计人员可以提高他们的创作,使移动用户界面看起来更有趣和吸引人. ...

  4. 3D拓扑自动布局之Node.js篇

    上篇将3D弹力布局的算法运行在Web Workers后台,这篇我们将进一步折腾,将算法运行到真正的后台:Node.js,事先申明Node.js篇和Web Workers篇一样,在这个应用场景下并不能提 ...

  5. ThreadLocal的基本原理与实现

    一.概念 首先,ThreadLocal并不是一个Thread,这个类提供了线程局部变量,这些变量不同于它们的普通对应物,因为访问某个变量的每个线程都有自己的局部变量,它独立于变量的初始化副本. 二.基 ...

  6. BI之SSAS完整实战教程2 -- 开发环境介绍及多维数据集数据源准备

    上一篇我们已经完成所有的准备工作,现在我们就开始动手,通过接下来的三篇文章创建第一个多维数据集. 传统的维度和多维数据集设计方法主要是基于现有的单源数据集. 在现实世界中,当开发商业智能应用程序时,很 ...

  7. ActiveReports 报表应用教程 (9)---交互式报表之动态排序

    在 ActiveReports 中除了提供对数据源进行排序的功能之外,还提供了最终用户排序功能,最终用户可以对报表进行区域内排序和整个数据源排序,结合数据钻取.过滤等功能可以让用户更方便地分析报表数据 ...

  8. Ubuntu配置任意版本的apt-get镜像

    我们知道,迄今为止,Ubuntu已有多个发行版,如11.04.11.10,以至于现在最新的16.*.而我们平常通过apt-get来安装软件,如果OS版本不同,那么镜像源的配置就不同,否则就会出现找不到 ...

  9. Ubuntu14.04安装ROOT集群

    之前尝试在CentOS7上部署ROOT集群,却发现无论是源码包安装,还是官方提供的二进制包,都缺少了关键的xproofd可执行文件,导致PoD不能运行.没有办法,只能尝试在其他OS上部署,这里我选择了 ...

  10. Represent code in math equations

    Introduce The article shows a way to use math equations to represent code's logical. Key ideas logic ...