Android线程池(二)
16lz
2021-01-23
本篇主要介绍Android自带的线程池的管理。
包含开始任务、重新加载、添加删除任务等,示例代码如下:
1 package com.jiao.threadpooltest; 2 3 import java.util.Iterator; 4 import java.util.Map; 5 import java.util.concurrent.ConcurrentHashMap; 6 import java.util.concurrent.ConcurrentLinkedQueue; 7 import java.util.concurrent.ConcurrentMap; 8 import java.util.concurrent.ExecutorService; 9 import java.util.concurrent.Executors; 10 import java.util.concurrent.Future; 11 12 import android.app.Activity; 13 import android.os.Bundle; 14 import android.os.Handler; 15 import android.os.Message; 16 import android.util.Log; 17 import android.view.View; 18 import android.view.View.OnClickListener; 19 import android.widget.ProgressBar; 20 import android.widget.Toast; 21 22 /** 23 * @TODO [线程池控制 ] 24 */ 25 public class MyRunnableActivity extends Activity implements OnClickListener { 26 27 /** 任务执行队列 */ 28 private ConcurrentLinkedQueue<MyRunnable> taskQueue = null; 29 /** 30 * 正在等待执行或已经完成的任务队列 31 * 32 * 备注:Future类,一个用于存储异步任务执行的结果,比如:判断是否取消、是否可以取消、 33 * 是否正在执行、是否已经完成等 34 * 35 * */ 36 private ConcurrentMap<Future, MyRunnable> taskMap = null; 37 38 /** 39 * 创建一个不限制大小的线程池 此类主要有以下好处 1,以共享的无界队列方式来运行这些线程. 40 * 2,执行效率高。 3,在任意点,在大多数nThreads 线程会处于处理任务的活动状态 41 * 4,如果在关闭前的执行期间由于失败而导致任何线程终止,那么一个新线程将代替它执行后续的任务(如果需要)。 42 * 43 * */ 44 private ExecutorService mES = null; 45 /** 46 * 在此类中使用同步锁时使用如下lock对象即可,官方推荐的,不推荐直接使用MyRunnableActivity.this类型的,可以详细读一下/ 47 * framework/app下面的随便一个项目 48 */ 49 private Object lock = new Object(); 50 51 /** 唤醒标志,是否唤醒线程池工作 */ 52 private boolean isNotify = true; 53 54 /** 线程池是否处于运行状态(即:是否被释放!) */ 55 private boolean isRuning = true; 56 57 /** 任务进度 */ 58 private ProgressBar pb = null; 59 60 /** 用此Handler来更新我们的UI */ 61 private Handler mHandler = null; 62 /** 63 * Overriding methods 64 * 65 * @param savedInstanceState 66 */ 67 @Override 68 protected void onCreate(Bundle savedInstanceState) { 69 super.onCreate(savedInstanceState); 70 setContentView(R.layout.my_runnable_main); 71 init(); 72 } 73 74 public void init() { 75 pb = (ProgressBar) findViewById(R.id.progressBar1); 76 findViewById(R.id.button1).setOnClickListener(this); 77 findViewById(R.id.button2).setOnClickListener(this); 78 findViewById(R.id.button3).setOnClickListener(this); 79 findViewById(R.id.button4).setOnClickListener(this); 80 findViewById(R.id.button5).setOnClickListener(this); 81 taskQueue = new ConcurrentLinkedQueue<MyRunnable>(); 82 taskMap = new ConcurrentHashMap<Future, MyRunnable>(); 83 if (mES == null) { 84 // 创建一个线程池 85 mES = Executors.newCachedThreadPool(); 86 } 87 88 // 用于更新ProgressBar进度条 89 mHandler = new Handler() { 90 /** 91 * Overriding methods 92 * 93 * @param msg 94 */ 95 @Override 96 public void handleMessage(Message msg) { 97 super.handleMessage(msg); 98 pb.setProgress(msg.what); 99 }100 101 };102 103 }104 105 /**106 * Overriding methods107 * 108 * @param v109 */110 @Override111 public void onClick(View v) {112 switch (v.getId()) {113 case R.id.button1:// 开始任务114 start();115 break;116 case R.id.button2:// 取消任务117 stop();118 break;119 case R.id.button3:// 重新加载120 reload(new MyRunnable(mHandler));121 break;122 case R.id.button4:// 释放资源123 release();124 break;125 case R.id.button5:// 添加任务126 addTask(new MyRunnable(mHandler));127 break;128 129 default:130 break;131 }132 }133 134 /**135 * <Summary Description>136 */137 private void addTask(final MyRunnable mr) {138 139 mHandler.sendEmptyMessage(0);140 141 if (mES == null) {142 mES = Executors.newCachedThreadPool();143 notifyWork();144 }145 146 if (taskQueue == null) {147 taskQueue = new ConcurrentLinkedQueue<MyRunnable>();148 }149 150 if (taskMap == null) {151 taskMap = new ConcurrentHashMap<Future, MyRunnable>();152 }153 154 mES.execute(new Runnable() {155 156 @Override157 public void run() {158 /**159 * 插入一个Runnable到任务队列中160 * 这个地方解释一下,offer跟add方法,试了下,效果都一样,没区别,官方的解释如下: 1 offer : Inserts161 * the specified element at the tail of this queue. As the queue162 * is unbounded, this method will never return {@code false}. 2163 * add: Inserts the specified element at the tail of this queue.164 * As the queue is unbounded, this method will never throw165 * {@link IllegalStateException} or return {@code false}.166 * 167 * 168 * */169 taskQueue.offer(mr);170 // taskQueue.add(mr);171 notifyWork();172 }173 });174 175 Toast.makeText(MyRunnableActivity.this, "已添加一个新任务到线程池中 !", 0).show();176 }177 178 /**179 * <Summary Description>180 */181 private void release() {182 Toast.makeText(MyRunnableActivity.this, "释放所有占用的资源!", 0).show();183 184 /** 将ProgressBar进度置为0 */185 mHandler.sendEmptyMessage(0);186 isRuning = false;187 188 Iterator iter = taskMap.entrySet().iterator();189 while (iter.hasNext()) {190 Map.Entry<Future, MyRunnable> entry = (Map.Entry<Future, MyRunnable>) iter191 .next();192 Future result = entry.getKey();193 if (result == null) {194 continue;195 }196 result.cancel(true);197 taskMap.remove(result);198 }199 if (null != mES) {200 mES.shutdown();201 }202 203 mES = null;204 taskMap = null;205 taskQueue = null;206 207 }208 209 /**210 * 重新加载211 */212 private void reload(final MyRunnable mr) {213 mHandler.sendEmptyMessage(0);//重置进度条214 if (mES == null) {215 mES = Executors.newCachedThreadPool();216 notifyWork();217 }218 219 if (taskQueue == null) {220 taskQueue = new ConcurrentLinkedQueue<MyRunnable>();221 }222 223 if (taskMap == null) {224 taskMap = new ConcurrentHashMap<Future, MyRunnable>();225 }226 227 mES.execute(new Runnable() {228 229 @Override230 public void run() {231 /** 插入一个Runnable到任务队列中 */232 taskQueue.offer(mr);233 // taskQueue.add(mr);234 notifyWork();235 }236 });237 238 mES.execute(new Runnable() {239 @Override240 public void run() {241 if (isRuning) {242 MyRunnable myRunnable = null;243 synchronized (lock) {244 myRunnable = taskQueue.poll(); // 从线程队列中取出一个Runnable对象来执行,如果此队列为空,则调用poll()方法会返回null245 if (myRunnable == null) {246 isNotify = true;247 }248 }249 250 if (myRunnable != null) {251 taskMap.put(mES.submit(myRunnable), myRunnable);252 }253 }254 }255 });256 }257 258 /**259 * <Summary Description>260 */261 private void stop() {262 263 Toast.makeText(MyRunnableActivity.this, "任务已被取消!", 0).show();264 265 for (MyRunnable runnable : taskMap.values()) {266 runnable.setCancleTaskUnit(true);267 }268 }269 270 /**271 * <Summary Description>272 */273 private void start() {274 275 if (mES == null || taskQueue == null || taskMap == null) {276 Log.i("KKK", "某资源是不是已经被释放了?");277 return;278 }279 mES.execute(new Runnable() {280 @Override281 public void run() {282 if (isRuning) {283 MyRunnable myRunnable = null;284 synchronized (lock) {285 myRunnable = taskQueue.poll(); // 从线程队列中取出一个Runnable对象来执行,如果此队列为空,则调用poll()方法会返回null286 if (myRunnable == null) {287 isNotify = true;288 // try289 // {290 // myRunnable.wait(500);291 // }292 // catch (InterruptedException e)293 // {294 // e.printStackTrace();295 // }296 }297 }298 299 if (myRunnable != null) {300 taskMap.put(mES.submit(myRunnable), myRunnable);301 }302 }303 304 }305 });306 }307 308 private void notifyWork() {309 synchronized (lock) {310 if (isNotify) {311 lock.notifyAll();312 isNotify = !isNotify;313 }314 }315 }316 }
更多相关文章
- [Android] 任意时刻从子线程切换到主线程的实现原理及加强版
- Android中handler的作用与线程
- Android -android程序最先加载的Activity
- android linker加载
- java|android加载src路径下面的图片文件
- 【Android】首次进入应用时加载引导界面
- android 加载有图的HTML
- android中的类加载和静态成员变量的初始化