多线程面试题总结

 新建、就绪、运行、阻塞、等待、超时等待、终止

最近面了三四家公司都有问到多线程的问题,所以今天在这里总结一下:

1.线程和进程的区别

①进程是操作系统分配资源的最小单元;

②线程是操作系统调度的最小单元;

③一个程序至少有一个进程;一个进程至少有一个线程;

④同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。

2.为什么要用线程池

因为创建线程和关闭线程的行为是非常耗时的,会显著降低软件的性能表现。解决办法就是先创建n条线程,循环使用,从而节约了创建线程和关闭线程的时间开销。

3.线程池的参数以及意义(https://www.jianshu.com/p/06570447efed)

  • corePoolSize:线程池核心线程数量
  • maximumPoolSize:线程池最大线程数量
  • keepAliverTime:当活跃线程数大于核心线程数时,空闲的多余线程最大存活时间
  • unit:存活时间的单位
  • workQueue:存放任务的队列
  • handler:超出线程范围和队列容量的任务的处理程序(线程池饱和策略)

当提交一个新任务,线程池的处理流程如下:

判断线程池中核心线程数是否已达阈值corePoolSize,若否,则创建一个新核心线程执行任务

若核心线程数已达阈值corePoolSize,判断阻塞队列workQueue是否已满,若未满,则将新任务添加进阻塞队列

若满,再判断,线程池中线程数是否达到阈值maximumPoolSize,若否,则新建一个非核心线程执行任务。若达到阈值,则执行线程池饱和策略

线程池饱和策略分为一下几种:

AbortPolicy:直接抛出一个异常,默认策略

DiscardPolicy: 直接丢弃任务

DiscardOldestPolicy:抛弃下一个将要被执行的任务(最旧任务)

CallerRunsPolicy:主线程中执行任务

4.创建线程的办法和创建线程池的办法

创建线程的办法

①继承一个Thread类
② 实现Runnable接口
③ 匿名内部类

创建线程池的办法

newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。

newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

5.线程中run和start的区别

调用start方法方可启动线程,而run方法只是thread类中的一个普通方法调用,还是在主线程里执行。

通过调用Thread类的 start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法

 

6.sleep和wait的区别

首先sleep和wait之间没有任何关系

sleep是Thread类的方法,指的是当前线程暂停。

wait是Object类的方法, 指的占用当前对象的线程临时释放对当前对象的占用,以使得其他线程有机会占用当前对象。 所以调用wait方法一定是在synchronized 中进行

7.sleep和yeild的区别

① sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;
② 线程执行sleep()方法后转入阻塞(blocked)状态,而执行yield()方法后转入就绪(ready)状态;
③ sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常;
④ sleep()方法比yield()方法(跟操作系统CPU调度相关)具有更好的可移植性。

posted @ 2022-04-03 19:13  塵暘  阅读(62)  评论(0编辑  收藏  举报