本篇主要介绍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 }