zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    2016.6.26考试
    爆搜。。。。。。。
    9.18目标
    9.17水题总结
    9.16测试
    9.10考试
    jzoj P1163 生日派对灯
    9.04考试总结
    8/8刷题记录
    a[i++]
  • 原文地址:https://www.cnblogs.com/all88/p/5195486.html
Copyright © 2011-2022 走看看