最近面了三四家公司都有问到多线程的问题,所以今天在这里总结一下:
1.线程和进程的区别
①进程是操作系统分配资源的最小单元;
②线程是操作系统调度的最小单元;
③一个程序至少有一个进程;一个进程至少有一个线程;
④同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。
2.为什么要用线程池
因为创建线程和关闭线程的行为是非常耗时的,会显著降低软件的性能表现。解决办法就是先创建n条线程,循环使用,从而节约了创建线程和关闭线程的时间开销。
3.线程池的参数以及意义(https://www.jianshu.com/p/06570447efed)
当提交一个新任务,线程池的处理流程如下:
判断线程池中核心线程数是否已达阈值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()方法