Android必备知识之线程和线程池

主线程处理页面交互逻辑(运行四大组件和处理它们和用户的交互),具有较高的响应速度,不能做耗时操作,所以需要子线程。3.0之后,如果在主线程做联网耗时操作,报NeworkOnMainThreadException异常。

1.AsyncTask 128

轻量级的异步任务类,封装了Thread和Handler它可以在线程池中执行后台任务,然后把执行进度和结果传递给主线程。不适合执行特别耗时的操作

class AsyncTask<Params, Progress, Result>

AsycnTask提供4个核心方法:

1.onPreExcecute()

2.doInBackground(Params…params)

3.onProgressUpdate(Progress…values)

4.onPostExecute(Result result)

2.HandlerThread

HandlerTread继承Thread,是一种可以使用Handler的Thread.

它的实现是:在run方法中通过Looper.prepare()来创建消息队列,并通过Looper.loop()来开启消息循环。

和普通Thread的不同:普通Thread在run方法中执行一个耗时任务,HandlerThread在内部创建了消息队列,外界需要通过Handler的消息方式通知HandlerThread执行一个具体的任务。

需要注意的点:HandlerThread的run方法是一个无限循环,当不再使用时,需要通过quit或者quitSafely关闭。

prepare()呢,中创建了一个Looper对象,并且把该对象放到了该线程范围内的变量中(sThreadLocal),在Looper对象的构造过程中,初始化了一个MessageQueue,作为该Looper对象成员变量。

loop()就开启了,不断的循环从MessageQueue中取消息处理了,当没有消息的时候会阻塞,有消息的到来的时候会唤醒。

3.Android中的线程池ThreadPoolExecutor

<1>线程池的优点:

重用线程池中的线程,避免因为线程的创建和销毁带来的性能消耗

能有效的控制线程的最大并发数,避免大量的线程之间因抢占系统资源而导致的阻塞现象

能够对线程进行简单的管理,并提供定时执行以及指定间隔循环执行等功能

<2>代码
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory(), defaultHandler);
}
corePoolSize

程池中的核心线程数

maximumPoolSize

最大线程池大小,当活动线程数达到这个值,后续任务会被阻塞

keepAliveTime

线程池中超过corePoolSize数目的非核心线程最大存活时间;闲置时的超时时长,超过这个值后,闲置线程就会被回收

unit

keepAliveTime 参数的时间单位。这是一个枚举

workQueue

执行前用于保持任务的队列,也就是线程池的缓存队列。此队列仅保持由 execute 方法提交的 Runnable

<3>四种线程池

1.FixedTreadPool

通过工厂方法类Executors的newFixedThreadPool方法创建。它是线程数量固定的线程池,仅有核心线程且没有超时策略,所以线程不会被回收。这意味着它能够快速的响应外界请求。

Runnable runnable = new Runnable() {
        @Override
        public void run() {
            Log.d("tag","sleep前");
            SystemClock.sleep(2000);
            Log.d("tag", "sleep后");
        }
    };
......

ExecutorService executorService = Executors.new FixedThreadPool(4);
    executorService.execute(runnable);
    executorService.execute(runable1);
    executorService.execute(runable2);
    executorService.execute(runable3);

结果:一次性执行四个前,然后四个后

2.CachedThreadPool

它是一种线程数量不定的线程池,只有非核心线程,可以简单理解为最大线程数是无限大的。CachedThreadPool的任务队列相当于一个空集合,这导致任何任务都会被立即执行,比较适合做一些大量的耗时较少的任务。

ExecutorService executorService = Executors.newCachedThreadPool();

3.ScheduledThreadPool

Scheduled有 “预定的” 意思。核心线程池的数量书固定的且非核心线程池是没有限制的,非核心线程池被闲置时会被立即回收。主要用于执行定时任务和具有固定周期的重复任务。

延迟1000秒执行

ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
    scheduledExecutorService.schedule(runnable,1000, TimeUnit.MILLISECONDS);
    scheduledExecutorService.schedule(runable1, 1000, TimeUnit.MILLISECONDS);
    scheduledExecutorService.schedule(runable2, 1000, TimeUnit.MILLISECONDS);
    scheduledExecutorService.schedule(runable3, 1000, TimeUnit.MILLISECONDS);
//延迟10ms后开始每1000ms执行一次runnable。
 scheduledExecutorService.scheduleAtFixedRate(runnable,10,1000,TimeUnit.MILLISECONDS);

4.SingleThreadExecutor

只有一个核心线程,所以确保所有的任务都是在一个线程里顺序执行。把所有的任务都放到一个线程,这样有一个好处是不需要处理线程同步问题。排着队依次执行,且不会乱序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值