Android线程池(二)

本篇主要介绍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 methods
107      * 
108      * @param v
109      */
110     @Override
111     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             @Override
157             public void run() {
158                 /**
159                  * 插入一个Runnable到任务队列中
160                  * 这个地方解释一下,offer跟add方法,试了下,效果都一样,没区别,官方的解释如下: 1 offer : Inserts
161                  * the specified element at the tail of this queue. As the queue
162                  * is unbounded, this method will never return {@code false}. 2
163                  * add: Inserts the specified element at the tail of this queue.
164                  * As the queue is unbounded, this method will never throw
165                  * {@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>) iter
191                     .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             @Override
230             public void run() {
231                 /** 插入一个Runnable到任务队列中 */
232                 taskQueue.offer(mr);
233                 // taskQueue.add(mr);
234                 notifyWork();
235             }
236         });
237 
238         mES.execute(new Runnable() {
239             @Override
240             public void run() {
241                 if (isRuning) {
242                     MyRunnable myRunnable = null;
243                     synchronized (lock) {
244                         myRunnable = taskQueue.poll(); // 从线程队列中取出一个Runnable对象来执行,如果此队列为空,则调用poll()方法会返回null
245                         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             @Override
281             public void run() {
282                 if (isRuning) {
283                     MyRunnable myRunnable = null;
284                     synchronized (lock) {
285                         myRunnable = taskQueue.poll(); // 从线程队列中取出一个Runnable对象来执行,如果此队列为空,则调用poll()方法会返回null
286                         if (myRunnable == null) {
287                             isNotify = true;
288                             // try
289                             // {
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 }

 

posted @ 2016-02-17 15:29  Android、Boy  阅读(188)  评论(0编辑  收藏  举报