android 艺术开发探索之线程和线程池

android 艺术开发探索之线程和线程池

我记得不管是在学校的时候还是在社会面试的时候,我都很害怕别个问我关于线程的问题,因为我什么也不知道,别人问的时候总喜欢说,简单说一下你对线程的理解?如何处理并发问题啥的,一问我三不知,下面就来理解下关于线程的知识点。

线程定义

android线程分为主线程和子线程,一个进程只有一个主线程,其他都是子线程也叫作工作线程,主线程处理和ui相关的任务,子线程处理耗时操作,从android3.0开始系统要求网络 访问必须在子线程执行,否则会报NetWorkOnMainThreadException.在安卓中扮演线程的角色有Thread ,AsyncTask,IntentService,HandlerThread

1.AsyncTask

AsyncTask封装了线程池和Handler方便开发者在子线程更新ui, AsyncTask类必须在主线程中加载,他的对象必须在主线程中创建,execute方法必须在ui线程调用,不能在程序中直接 调用其OnpreExecute,onPostExecute,doInBackground和OnProgressUpdate,一个AsyncTask对象只能执行一次,即只
能调用一次execute方法,具体查看文章http://blog.csdn.net/u013200864/article/details/46792551


2. HandlerThread

Thread线程是一次性消费品,当Thread线程执行完一个耗时的任务之后,线程就会被自动销毁了。如果此时我又有一个耗时任务需要执行,我们不得不重新创建线程去执行该耗时任务。然而,这样就存在一个性能问题:多次创建和销毁线程是很耗系统资源的所以使用HandlerThread。
HandlerThread是一个具有消息循环系统的线程,他的内部可以使用Handler,其继承了Thread,handler的工作是需要looper的,可以看我的这篇文章:http://blog.csdn.net/u013200864/article/details/52131675,所以说HandlerThread 只是一个线程里面获取了looper。并且默认创建好了handler的线程,省去了我们自己构建消息循环系统的步骤,和主线程的handler的原理一样,只是默认的Handler是调用的主线程的looper,而这个HandlerThread是子线程里面自己获取了looper构建了消息循环系统。IntentService内部采用 HandlerThread执行任务,任务完成自动退出,不容易被杀死。

public class MainActivity extends Activity {
    HandlerThread handlerThread = new HandlerThread("张晓雅");
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        handlerThread.start();
        final Handler handler = new Handler(handlerThread.getLooper()){

            @Override
            public void handleMessage(Message msg) {
                Log.e("TAG", "thecurrent thread is" + Thread.currentThread());
                try{
                    handlerThread.sleep(1000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }

                super.handleMessage(msg);
            }
        };
        for(int i = 0;i<5;i++){
            handler.sendMessage(Message.obtain());
        }
    }
}

还看不懂的看这里https://github.com/square/picasso/blob/master/picasso/src/main/java/com/squareup/picasso/Dispatcher.java


3. IntentService

IntentService是个抽象类继承了Service,只有实现子类才可以用它的特性,它类部有一个ServiceHandler继承了handler, start方法里面通过ServiceHandler发了一个消息,ServiceHandler类接收消息同时执行onHandleIntent抽象方法,stopSelf。oncreated中HandlerThread的looper传递给了ServiceHandler,所以我们实现onHandleIntent方法就好,通过如下方法启动:

Intent intent=new Intent();
intent.setClass(context, MyIntentService.class);
intent.putExtra(“task”, “task1”);//定时扫描的时间间隔

在MyIntentService里面实现onHandleIntent用switch来判断task是哪一个任务,然后做相应的耗时操作,当所有的耗时操作完成后他就会自己终止服务。 IntentService和一般的服务相比它会自己在耗时操作完成后自己终止,然后就是在它里面做耗时操作的时候不需要自己创建thread。

线程池

线程是操作系统最小单元,创建销毁都有相应开销,当有大量线程时,系统会用时间片轮转的方式调度每个线程,因此线 程无法做到绝对并行,当有大量线程时应采用线程池的方式,这样节省资源。

ThreadPoolExecutor类是线程池真正实现,构造器如下:
 /**
      * 创建一个线程池
      *
      * @param corePoolSize  线程池的核心线程数,即使处于空闲状态也会存活
      * @param maximumPoolSize 池子里面能装的最大线程数,当活动线程数到达这个数值后,后续新的任务会阻塞
      * @param keepAliveTime当allowCoreThreadTimeOut设为true的时候,keepAliveTime也会作用于核心线程的超时策略
      *         当其不为true的时候是指非核心线程闲置的时长,超过这个时间都会被回收
      * @param unit ,keepAliveTime时间的单位,枚举,有秒,毫秒,分钟
      * @param workQueue 线程池的任务队列,通过execute方法提交的Runable会存储在这个参数中
      */
     public ThreadPoolExecutor(int corePoolSize,
                               int maximumPoolSize,
                               long keepAliveTime,
                               TimeUnit unit,
                               BlockingQueue<Runnable> workQueue) {
         this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
              Executors.defaultThreadFactory(), defaultHandler);
     }

android中的线程池分为4类

  Runnable mRunnable=new Runnable() {
        @Override
        public void run() {
            SystemClock.sleep(2000);
        }
    };
    // 建立一个容量为3的固定尺寸的线程池,只有核心线程,无超时设置,线程数量固定,线程池关闭后才会回收,它能够更加快速地响应外界请求
    ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(3);
    newFixedThreadPool.execute(mRunnable);

    //线程数量不固定的线程池,只有非核心线程,最大线程数为Integer.MaxValue,有空闲的就用空闲的, 没空闲的就创建新线程,闲置线程的超时时间为60秒,任何任务都会被立即执行,这类线程池比较适合执行大量耗时较少的任务,它几乎是不占用任何系统资源的
    ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
    newCachedThreadPool.execute(mRunnable);

    //它的核心线程数固定,而非核心线程数没有限制,并且当非核心线程闲置时会被立即回收,主要用于执行定时任务和具有固定周期的重复任务
    ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(4);
    //2000MS后执行
    newScheduledThreadPool.schedule(mRunnable,2000,TimeUnit.MILLISECONDS);
    //延迟10ms后,每隔1000ms执行一次mRunnable
    newScheduledThreadPool.scheduleAtFixedRate(mRunnable,10,1000,TimeUnit.MILLISECONDS);

    //内部只有一个核心线程,他确保所有的任务都在同一个线程中按顺序执行,无需处理线程同步问题
    ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
    newSingleThreadExecutor.execute(mRunnable);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值