本篇主要介绍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. 2014 网选 5012 Dice(bfs模板)

    /* 题意:就是给定两个筛子,每个筛子上6个面,每个面的数字属于[1,6], 且互不相同! 问a筛子最少经过按照题目规定的要求转动,达到和b筛子上下左右前后的数字相同! 思路:很直白的bfs,将每一种 ...

  2. maven -- 问题解决(一)解决eclipse中maven项目出现的问题

    配置项目时出现的错误: error: Cannot change version of project facet Dynamic Web Module to 2.5. error: One or m ...

  3. 关于4K Block Size的Device和 Aligned IO

    背景:最近采购了一批新的服务器,底层的存储设备的默认physical sector size从原有的 512B 改为了 4K. 装完系统以后,在做数据库物理备份恢复时xtrabackup报了这么一个错 ...

  4. IP Failover Setup using Keepalived on CentOS/Redhat 6

    source url:http://tecadmin.net/ip-failover-setup-using-keepalived-on-centos-redhat-6/ Keepalived is ...

  5. 谷歌联合 Adobe 发布 Noto 字体【免费下载】

    Noto 涵盖了世界上所有主要语言,包括欧洲,非洲,中东,印度语,南亚和东南亚,中亚,美洲和东亚语言.也支持几个少数民族和历史语言.不久前,还发布了针对文.日文.韩文的开源字体——Noto Sans ...

  6. static、final、static final 用法

    1.使用范围:类.方法.变量.2.区别和联系:2.1.static 含义:静态的,被 static 修饰的方法和属性只属于类不属于类的任何对象.2.2.static 用法:2.2.1.static 可 ...

  7. C#语法糖之 cache操作类 asp.net

    因为考虑到我下面我将写session cookies 等 操作类 ,与cache具有共性. 所以都统一继承了IHttpStorageObject  abstract class 来保函数风格的统一 , ...

  8. ASP.NET MVC5---通过QueryString传值

    1.首先我们来看看普通的传值是啥样的.如图所示,我们普通的传值是这样的 public ActionResult Edit(int?id) { if (id == null) { return new ...

  9. Codeforces Round #313 (Div. 1) B. Equivalent Strings

    Equivalent Strings Problem's Link: http://codeforces.com/contest/559/problem/B Mean: 给定两个等长串s1,s2,判断 ...

  10. HTML5 语义元素

    返回目录 http://hovertree.com/h/bjaf/html5zixueji.htm 一个语义元素能够清楚的描述其意义给浏览器和开发者.无语义 元素实例: <div> 和 & ...