学习笔记 | Android开发艺术之线程和线程池

一、知识储备

线程:操作系统调度的最小单元
主线程(UI线程):默认情况下一个进程只有一个主线程,主要处理界面交互相关的逻辑
子线程(工作线程):主线程以外的线程都是子线程,执行耗时任务

Q:如何避免频繁创建和销毁线程所带来的系统开销?
A:采用线程池,池中会缓存一定数量的线程,进而达到效果。

二、线程的形态

线程的形态

AsyncTask

AsyncTask是一个抽象的泛型类

a. 3个泛型参数

  • Params:表示参数的类型
  • Progress:表示后台任务的执行进度的类型
  • Result:表示后台任务的返回结果的类型
  • 若没有传递具体的参数,这三个泛型参数都可使用void
//含义:在执行AsyncTask时不需要传入参数给后台任务、使用整型数据来作为进度显示单位,最后使用布尔型数据来反馈执行结果
public abstract class AsyncTask<Void, Integer, Boolean>

b. 4个核心方法

  • onPreExecute():在主线程中执行,在异步任务执行之前,一般做一些UI控件的初始化的操作。
  • doInBackground(Params...params):在线程池中执行,用于执行异步任务,params参数表示异步任务的输入参数。在此方法中可以通过publishProgress方法来更新任务的进度,publishProgress方法会调用onProgressUpdate方法。另外此方法需要返回计算结果给onPostExecute方法。
  • onProgressUpdate(Progress...values):在主线程中执行,利用方法中携带的参数如Progress来对UI进行相应地更新
  • onPostExecute(Result result):在主线程中执行,在异步任务执行之后,此方法会被调用,其中result参数是doInBackground的返回值。

说明:doInBackground和onProgressUpdate方法它们的参数中均包含…的字样,在Java中…表示参数的数量不定,它是一种数组型参数.

c. 条件限制

  • AsyncTask对象必须在主线程创建
  • 不要直接调用onPreExecute()、doInBackground()、onProgressUpdate()、onPostExecute)和onCancelled()方法
  • execute方法必须在UI线程调用
  • 一个AsyncTask对象只能执行一次,即只能调用一次execute方法,否则会报运行时异常

d. 工作原理

  • 内部有一个静态的Handler对象即InternalHandler:

    作用:将执行环境从线程池切换到主线程;通过它来发送任务执行的进度以及执行结束等消息。

    注意:必须在主线程中创建

  • 内部有两个线程池:

    SerialExecutor:用于任务的排队,默认是串行的线程池
    THREAD_POOL_EXECUTOR:用于真正执行任务

  • 排队执行过程:
    (1)把参数Params封装为FutureTask对象,相当于Runnable;
    (2)调用SerialExecutor.execute()将FutureTask插入到任务队列tasks中;
    (3)若没有正在活动的AsyncTask任务,则就会执行下一个AsyncTask任务。执行完毕后会继续执行其他任务直到所有任务都完成,即默认使用串行方式执行任务。

HandlerThread

HandlerThread是一个线程类,它继承自Thread

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

a. HandlerThread实现方法

  • 实例化一个HandlerThread对象,参数是该线程的名称;
  • 通过 HandlerThread.start()开启线程;
  • 实例化一个Handler并传入HandlerThread中的looper对象,使得与HandlerThread绑定;
  • 利用Handler即可执行异步任务;
  • 当不需要HandlerThread时,通过HandlerThread.quit()/quitSafely()方法来终止线程的执行。
private HandlerThread myHandlerThread ;  
private Handler handler ;  
@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
   setContentView(R.layout.activity_main);  
   //实例化HandlerThread
   myHandlerThread = new HandlerThread("myHandler") ;  
   //开启HandlerThread
   myHandlerThread.start();  
   //将Handler对象与HandlerThread线程绑定
   handler =new Handler(myHandlerThread.getLooper()){  
       @Override  
        publicvoid handleMessage(Message msg) {  
           super.handleMessage(msg);  
            // 这里接收Handler发来的消息,运行在handler_thread线程中  
            //TODO...  
        }  
    };  
   
   //在主线程给Handler发送消息  
   handler.sendEmptyMessage(1) ;  
   new Thread(new Runnable() {  
       @Override  
        publicvoid run() {  
           //在子线程给Handler发送数据  
           handler.sendEmptyMessage(2) ;  
        }  
    }).start();  
}  
@Override  
protected void onDestroy() {  
   super.onDestroy();  
   //终止HandlerThread运行
   myHandlerThread.quit() ;  
}  

b. 用途

  • 进行串行异步通信
  • 构造IntentService
IntentService

IntentService是一个继承自Service的抽象类

a. 优点

  • 相比于线程:由于是服务,优先级比线程高,更不容易被系统杀死。比较适合执行一些高优先级的后台任务。
  • 相比于普通Service:可自动创建子线程来执行任务,且任务执行完毕后自动退出。

b. 工作原理

  • IntentService.onCreate()里创建一个Handle对象即HandlerThread,利用其内部的Looper会实例化一个ServiceHandler对象;

  • 任务请求的Intent会被封装到Message并通过ServiceHandler发送给Looper的MessageQueue,最终在HandlerThread中执行;

  • ServiceHandler.handleMessage()中会调用IntentService.onHandleIntent(),可在该方法中处理后台任务的逻辑。
    在这里插入图片描述
    补充:IntentService会通过stopSelf(int startId)方法来尝试停止服务

    Q:为什么采用stopSelf(int startId)而不是stopSelf()来停止服务呢?
    A:因为stopSelf()会立刻停止服务,而这个时候可能还有其他消息未处理,stopSelf(int startId)则会等待所有的消息都处理完毕后才终止服务。

三、线程池

a. 优点
  • 重用线程池中的线程,避免因为线程的创建和销毁所带来的性能开销。
  • 能有效控制线程池的最大并发数,避免大量的线程之间因互相抢占系统资源而导致的阻塞现象。
  • 进行线程管理,并提供定时执行以及指定间隔循环执行等功能。
b. ThreadPoolExecutor
//构造参数
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) 
  • corePoolSize:核心线程数
    1、 默认情况下,核心线程会在线程中一直存活
    2、当设置ThreadPoolExecutor的allowCoreThreadTimeOut属性为

  • true:表示核心线程闲置超过超时时长,会被回收;

  • false:表示核心线程不会被回收,会在线程池中一直存活。

  • maximumPoolSize:最大线程数
    当活动线程数达到这个数值后,后续的任务将会被阻塞。

  • keepAliveTime:非核心线程超时时间

  • 超过这个时长,非核心线程就会被回收。

  • 当ThreadPool-Executor的allowCoreThreadTimeOut属性设置为true时,keepAliveTime同样会作用于核心线程。

  • unit:用于指定keepAliveTime参数的时间单位
    单位有:TimeUnit.MILLISECONDS、TimeUnit.SECONDS、TimeUnit.MINUTES等。

  • workQueue:任务队列
    通过线程池的execute()方法提交的Runnable对象会存储在这个参数中。

  • threadFactory:线程工厂,可创建新线程
    是个接口,只有一个方法Thread newThread(Runnable r)。

  • handler:在线程池无法执行新任务时进行调度

    ThreadPoolExecutor执行任务时遵循如下规则:
    • 若程池中的线程数量未达到核心线程数,则会直接启动一个核心线程执行任务。

    • 若线程池中的线程数量已达到或者超过核心线程数量,则任务会被插入到任务列表等待执行。

      若任务无法插入到任务列表中,往往由于任务列表已满,此时如果

      • 线程数量未达到线程池最大线程数,则会启动一个非核心线程执行任务;
      • 线程数量已达到线程池规定的最大值,则拒绝执行此任务,ThreadPoolExecutor会调用RejectedExecutionHandler的rejectedExecution方法来通知调用者。
补充:
核心线程数等于CPU核心数+1;
线程池的最大线程数为CPU核心数的2倍+1;
核心线程无超时机制,非核心线程在闲置时的超时时间为1秒;
任务队列的容量为128
c.线程池的分类
  • FixedThreadPool

    含义:线程数量固定的线程池,所有线程都是核心线程,当线程空闲时不会被回收。

    特点:能快速响应外界请求。

  • CachedThreadPool

    含义:线程数量不定的线程池(最大线程数为Integer.MAX_VALUE),只有非核心线程,空闲线程有超时机制,超时回收。

    特点:适合执行大量的耗时较少的任务

  • ScheduledThreadPool

    含义:核心线程数量固定,非核心线程数量不定。

    特点:用于执行定时任务和固定周期的重复任务。

  • SingleThreadExecutor

    含义:只有一个核心线程,可确保所有的任务都在同一个线程中按顺序执行。

    特点:无需处理线程同步问题。

基于SSM框架的智能家政保洁预约系统,是一个旨在提高家政保洁服务预约效率和管理水平的平台。该系统通过集成现代信息技术,为家政公司、家政服务人员和消费者提供了一个便捷的在线预约和管理系统。 系统的要功能包括: 1. **用户管理**:允许消费者注册、登录,并管理他们的个人资料和预约历史。 2. **家政人员管理**:家政服务人员可以注册并更新自己的个人信息、服务类别和服务时间。 3. **服务预约**:消费者可以浏览不同的家政服务选项,选择合适的服务人员,并在线预约服务。 4. **订单管理**:系统支持订单的创建、跟踪和管理,包括订单的确认、完成和评价。 5. **评价系统**:消费者可以在家政服务完成后对服务进行评价,帮助提高服务质量和透明度。 6. **后台管理**:管理员可以管理用户、家政人员信息、服务类别、预约订单以及处理用户反馈。 系统采用Java语言开发,使用MySQL数据库进行数据存储,通过B/S架构实现用户与服务的在线交互。系统设计考虑了不同用户角色的需求,包括管理员、家政服务人员和普通用户,每个角色都有相应的权限和功能。此外,系统还采用了软件组件化、精化体系结构、分离逻辑和数据等方法,以便于未来的系统升级和维护。 智能家政保洁预约系统通过提供一个集中的平台,不仅方便了消费者的预约和管理,也为家政服务人员提供了一个展示和推广自己服务的机会。同时,系统的后台管理功能为家政公司提供了强大的数据支持和决策辅助,有助于提高服务质量和管理效率。该系统的设计与实现,标志着家政保洁服务向现代化和网络化的转型,为管理决策和控制提供保障,是行业发展中的重要里程碑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值