本篇主要介绍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. Maven进价:eclipse中集成maven

    一.M2Eclipse插件 m2eclipse是一个在Eclipse中集成Maven的插件,有了该插件,用户可以方便的在Eclipse中执行Maven命令.创建Maven项目.修改POM文件等. 下载 ...

  2. 【解决方案】VS2013外部工具中添加ildasm.exe

    VS2013安装在Win8.1的操作系统中,开始屏幕中找不到ildasm.exe没有显示,于是下面提供了一种方法将ildasm.exe工具添加到VS2013外部工具中,并将反编译的代码输出到VS201 ...

  3. 探索jdk8之ConcurrentHashMap 的实现机制

    在介绍ConcurrentHashMap源码之前,很有必要复习下java并发编程中的一些基础知识,比如内存模型等. 存储模型 并发编程中的三个概念 1.原子性 2.可见性 3.重排序 对HashMap ...

  4. WCF回顾一、基本概念和应用场景

    一.WCF描述 wcf是一款基于面向服务的架构的通讯框架平台,在分布式框架中得到了广泛使用. wcf入门非常简单,只要花几分钟就能编写一个完整的wcf程序,而实际上WCF是概念非常多的一门技术,需要花 ...

  5. Sprint第三个冲刺(第一天)

    一.Sprint介绍 任务进度: 二.Sprint周期 看板: 燃尽图:

  6. 用Qt写软件系列四:定制个性化系统托盘菜单

    导读 一款流行的软件,往往会在功能渐趋完善的时候,通过改善交互界面来提高用户体验.毕竟,就算再牛逼的产品,躲藏在糟糕的用户界面之后总会让用户心生不满.界面设计需综合考虑审美学.心理学.设计学等多因素, ...

  7. 重温html5的新增的标签和废除的标签

    HTML5已经盛行有段时间了,对于标签的使用,按照规范,哪些该用,哪些不该用,你是否都掌握了呢.今天我在这里详细列举下: 新增的结构标签 section元素 表示页面中的一个内容区 块,比如章节.页眉 ...

  8. 【JS复习笔记】03 继承

    关于继承 好吧,说到底JS还是原型继承的,而不是类继承.所以在这个上面要经常用到prototype去继承另一个对象. 所有的构造器函数都约定命名为首字母大写的形式,并且不以首字母大写的形式拼写任何其它 ...

  9. HDU 1069---背包---Monkey and Banana

    HDU 1069 Description A group of researchers are designing an experiment to test the IQ of a monkey. ...

  10. 使用PowerQuery操作OData数据

             Excel是我们耳熟的办公软件.PowerQuery是一个允许连接多种数据源的Excel插件.它能从一个网页上智能查询数据.使用PowerQuery能合并数据集使用join,merg ...