美文网首页
线程和线程池

线程和线程池

作者: 要学的东西太多了 | 来源:发表于2018-10-11 17:45 被阅读0次

1.AsyncTask内部封装了ThreadHandler,可以在线程池中执行后台任务,然后把任务进度和结果传递给主线程并在主线程中更新UI,不过并不适合执行特别耗时的任务。

2.AsyncTask是个抽象的泛型类,有三个泛型参数:params(参数的类型)、progress(后台任务执行进度的类型)、result(后台任务返回的类型)。常用用法如下:

AsyncTask<String,Integer,String> asyncTask=new AsyncTask<String, Integer, String>() {


            @Override
            protected void onPreExecute() {//主线程中执行,做一些准备工作
                super.onPreExecute();
            }

            @Override
            protected String doInBackground(String... strings) {//线程池中执行,做耗时操作
                //publishProgress用来更新进度,会调用onProgressUpdate方法
                publishProgress(3);
                return null;
            }

            @Override
            protected void onProgressUpdate(Integer... values) {//主线程中执行,用于更新进度
                super.onProgressUpdate(values);
            }

            @Override
            protected void onPostExecute(String s) {//主线程中执行,任务执行完后返回结果
                super.onPostExecute(s);
            }

            @Override
            protected void onCancelled() {//主线程中执行,任务取消的时候调用
                super.onCancelled();
            }
        };

3.使用AsyncTask需要注意以下几点:

1.AsyncTask必须在主线程初始化,因为内部有Handler必须要在主线程初始化;
2.execute方法必须在主线程调用且同一个AsyncTask对象只能调用一次;
3.不要手动调用AsyncTask的回调方法;
4.Android3.0后AsyncTask采用串行执行任务,要并行可以用executeOnExecutor方法。

4.AsyncTask的工作原理:调用AsyncTaskexecute方法→调用executeOnExecutor方法→调用onPreExecute方法,然后线程池开始执行→将params参数封装成FutureTask对象,并在SerialExecutorexecute方法里将FutureTask对象插入mTask队列里→如果现在没有正在执行的任务,调用scheduleNext方法,在scheduleNext方法里调用THREAD_POOL_EXECUTOR.execute方法真正执行任务。调用FutureTaskrun方法时会去调用WorkerRunnablecall方法,call方法会先把mTaskInvoked设为true,表示这个任务已经执行过了,然后调用doInBackground方法,并将其结果值传递给postResult方法,postResult方法里面通过handler发送消息切换到主线程,并调用AsyncTaskfinish方法,在finish方法里面调用onPostExecute方法。

5.IntentService是一个继承Service的抽象类,用于执行耗时任务,任务执行完毕后会自动停止,其优点是它是服务,比线程的优先级高,不容易被系统杀死。IntentService内部封装了HandlerThreadHandlerHandlerThread继承了Threadrun()方法里初始化了Looper并开启了消息循环,IntentService初始化的时候,会新建一个HandlerThread对象,并调用其start()方法,然后获取HandlerThreadLooper对象并用来创建Handler。启动服务的时候,会在onStartCommand方法中调用onStart方法,在onStart方法里通过这个handler发消息,最后被HandlerThread调用onHandleIntent(这里就是我们需要重写并做逻辑处理的地方)处理,如果任务都完了还会调用stopself方法关闭服务。

6.线程池的优点如下:

1.重用线程,减少线程创建和销毁带来的性能开销。
2.有效控制线程的并发数,防止抢夺系统共享资源造成的阻塞。
3.对线程进行管理,比如定时执行或指定间隔循环等。

7.ThreadPoolExecutorExecutor的具体实现,构造方法为:

ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory)

corePoolSize表示核心线程数,默认情况下核心线程是一直存活的,通过ThreadPoolExecutorallowCoreThreadTimeOut(ture)可以让闲置的核心线程在等待新任务超过keepAliveTime的时候被终止。
maximumPoolSize表示最大线程数,超过这个数值的线程会被阻塞。
keepAliveTime表示超时时间,非核心线程闲置时,等待新任务超过这个时间就会被回收。
unit表示keepAliveTime的单位。
workQueue表示任务队列,execute方法会将一个runnable对象存储在里面。
threadFactory表示线程工厂,为线程池提供创建新线程的功能。

8.ThreadPoolExecutor执行任务的规则如下:

1.核心线程数量未满时创建一个核心线程执行任务。
2.核心线程数量已满,任务插入到任务队列等待执行。
3.如果任务队列无法继续插入,表示任务队列已满,如果线程数量未达到最大线程数量,就开启一个非核心线程来执行任务。
4.如果已经达到最大线程数,就拒绝任务。

9.Android中常见的四种线程池,返回类型都是ExecutorService,一般需要强转为ThreadPoolExecutorThreadPoolExecutorAbstractExecutorService的子类,而AbstractExecutorService实现了ExecutorService接口:
(1)FixedThreadPool,通过Executors.newFixedThreadPool()方法创建。线程数量固定,且都是核心线程,即空闲不会回收。此外,它没有超时限制,任务队列大小是无限制的。
(2)CachedThreadPool,通过Executors.newCachedThreadPool()方法创建。线程数量不固定,只有非核心线程,最大线程数为Integer.MAX_VALUE,有60秒的超时。
(3)ScheduledThreadPool,通过Executors.newScheduledThreadPool()方法创建。核心线程数固定,非核心线程数无限制,可以执行定时任务。
(4)SingleThreadExecutor,通过Executors.newSingleThreadExecutor()方法创建。只有一个核心线程,所有的任务都在这个核心线程顺序执行。

相关文章

  • Springboot | 线程池的学习,多线程池配置示例

    一、线程和进程,线程的生命周期二、单线程和多线程三、线程池的概念四、线程池的使用五、多线程池配置示例 一、线程和进...

  • 线程池查漏补缺

    tomcat线程池和jdk线程池区别 概述 线程池是什么,为什么要线程池 jdk有哪些线程池和原理 第三方中间件的...

  • 线程池概述

    为什么要使用线程池? 线程池核心参数 线程池的几种拒绝策略 execute()和submit()的区别 线程池工作...

  • java线程池

    线程VS线程池 普通线程使用 创建线程池 执行任务 执行完毕,释放线程对象 线程池 创建线程池 拿线程池线程去执行...

  • 第九章 线程池

    线程池的实现原理和使用建议。 当提交一个新任务到线程池时,线程池的处理流程如下。1)线程池判断核心线程池里的线程是...

  • 我们的线程被饿死了

    我们的线程被饿死了 我们在构建线程池的时候可以构建单个线程的线程池和多个线程的线程池。 那么线程池使用不当可不可能...

  • Android线程池的使用

    一、线程与线程池,为什么要使用线程池 1、Android中的线程 在Android中有主线程和子线程的区分。主线程...

  • Java线程池的使用

    线程类型: 固定线程 cached线程 定时线程 固定线程池使用 cache线程池使用 定时调度线程池使用

  • Android面试Java基础篇(二)

    (一)问:Java线程池的实现原理和使用 线程池即存放和管理线程的一个池子 (1)复用线程池中的线程,避免因为线程...

  • java----线程池

    什么是线程池 为什么要使用线程池 线程池的处理逻辑 如何使用线程池 如何合理配置线程池的大小 结语 什么是线程池 ...

网友评论

      本文标题:线程和线程池

      本文链接:https://www.haomeiwen.com/subject/snebaftx.html