Android并发编程高级面试题汇总(含详细解析 十三)
  CpwfxCg9mmk0 2023年11月02日 68 0

Android并发编程高级面试题汇总最全最细面试题讲解持续更新中👊👊 👀你想要的面试题这里都有👀 👇👇👇

线程池管理线程原理

这道题想考察什么?

是否了解线程池相关的理论知识

考察的知识点

  1. 线程中的基本概念,线程的生命周期
  2. 线程池的原理
  3. 常见的几种线程池的特点以及各自的应用场景

考生应该如何回答

在一个应用程序中,我们需要多次使用线程,也就意味着,我们需要多次创建并销毁线程。而创建并销毁线程的过程势必会消耗内存。而在Java中,内存资源是及其宝贵的,所以,我们就提出了线程池的概念。线程池的好处,就是可以方便的管理线程,也可以减少内存的消耗。

线程池的创建
public ThreadPoolExecutor(int corePoolSize,  
                              int maximumPoolSize,  
                              long keepAliveTime,  
                              TimeUnit unit,  
                              BlockingQueue<Runnable> workQueue,  
                              ThreadFactory threadFactory,  
                              RejectedExecutionHandler handler)
  1. corePoolSize :核心线程数量,默认情况下,线程池会一直维护corePoolSize个线程,让这些线程不会被回收。
  2. maximumPoolSize:线程池最大线程的数量;
  3. keepAliveTime:线程的最长闲置时间,若线程闲置超过此时间则回收;
  4. util:闲置时间单位;
  5. workQueue:等待队列,当线程池中执行的任务超过核心线程数后,新提交任务将加入此队列等待执行;
  6. threadFactory:创建线程的线程工厂
  7. handler:拒绝策略,在任务满了之后,如何处理继续添加的任务。
线程池的执行流程

Android并发编程高级面试题汇总(含详细解析 十三)_阻塞队列

在新建的线程池中,默认最开始里面是没有线程的。当然,可以使用prestartAllCoreThreads方法,来提前把corePoolSize的核心线程。

向线程池中提交任务时,首先判断线程池中正在执行的线程数是否已经达到核心线程数:

  • 未达到:创建新线程执行任务
  • 达到:将任务添加进入任务队列

在向任务队列添加任务时,可能添加成功,也可能添加失败:

  • 成功:等待其他线程执行完成,将会自动从队列中获取任务继续执行;
  • 失败:判断当前线程池线程数是否达到最大线程数

若添加队列失败,在判断是否达到最大线程数是也可能存在两种结果:

  • 达到:回调RejectedExecutionHandler拒绝策略,JDK提供了四种拒绝策略处理类:AbortPolicy(抛出一个异常,默认的),DiscardPolicy(直接丢弃任务),DiscardOldestPolicy(丢弃队列里最老的任务,将当前这个任务继续提交给线程池),CallerRunsPolicy(交给线程池调用所在的线程进行处理)
  • 未达到:创建新线程执行任务
核心线程

默认情况下,线程池会一直维护核心线程,使其不被回收。

可以使用allowCoreThreadTimeOut(true)设置核心线程也会被闲置回收。

线程池运行线程执行任务:

while (task != null || (task = getTask()) != null) {
    //......
    task.run();
}

其中getTask则会从队列中获取待执行任务,不断执行。如果当前队列中没有待执行任务,非核心线程会等待指定的keepAliveTime时间到达后正常退出线程,而核心线程会通过任务队列的take方法阻塞,从而保证其持续运行。

Runnable r = timed ?
					//非核心线程
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
					//核心线程
                    workQueue.take();

线程池有几种实现方式,线程池的七大参数有哪些? (美团)

这道题想考察什么?

是否了解线程池的七大参数有哪些与真实场景使用,是否熟悉线程池的七大参数有哪些

考察的知识点

线程池的七大参数有哪些的概念在项目中使用与基本知识

考生应该如何回答

七大参数
  1. corePoolSize
    线程池中的常驻核心线程数
  2. maximumPoolSize
    线程池能够容纳同时执行的最大线程数,此值必须大于等于1
  3. keepAliveTime
    空闲线程的存活时间。
  4. unit
    keepAliveTime的单位
  5. workQueue
    任务队列,被提交但尚未被执行的任务
  6. threadFactory
    表示生成线程池中工作线程的线程工厂,用于创建线程一般默认即可
  7. handler:
    拒绝策略,表示当队列满了并且工作线程大于等于线程池最大线程数(maximumPoolSize)时如何处理
实现方式

使用JDK中自带的线程池可以通过创建ThreadPoolExecutor线程池对象,也能够通过Executors中定义的静态方法。其中Executors静态方法创建的线程池主要有以下类型:

1.newSingleThreadExecutor

创建只有一个线程的线程池,且线程的存活时间是无限的;当该线程正繁忙时,对于新任务会进入阻塞队列中(无界的阻塞队列)

适用:一个任务一个任务执行的场景

2.newCachedThreadPool

当有新任务到来,则插入到SynchronousQueue中,由于SynchronousQueue是同步队列,因此会在池中寻找可用线程来执行,若有可以线程则执行,若没有可用线程则创建一个线程来执行该任务;若池中线程空闲时间超过指定大小,则该线程会被销毁。

适用:执行很多短期异步的场景

3.newFixedThreadPool

创建可容纳固定数量线程的池子,每隔线程的存活时间是无限的,当池子满了就不在添加线程了;如果池中的所有线程均在繁忙状态,对于新任务会进入阻塞队列中(无界的阻塞队列),但是,在线程池空闲时,即线程池中没有可运行任务时,它不会释放工作线程,还会占用一定的系统资源。

适用:长期执行的场景

4.NewScheduledThreadPool

创建一个固定大小的线程池,线程池内线程存活时间无限制,线程池可以支持定时及周期性任务执行,如果所有线程均处于繁忙状态,对于新任务会进入DelayedWorkQueue队列中,这是一种按照超时时间排序的队列结构

适用:周期性执行的场景


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

CpwfxCg9mmk0