1. 线程与进程的区别?
线程是CPU调度和分派的基本单位;
进程是系统调度和分配资源的基本单位;
2. 实现多进程的三种方式
- 继承Thread类
- 实现Runnable接口
- 线程池
3. 继承Thread类与实现Runnable接口的区别(实现接口的优势)
(也是创建线程的两种方式)
- 继承只能单继承,接口可以实现多个接口;
- (实现接口)适合多个线程共享代码;
- (实现接口)增加程序健壮性:线程共享代码,数据和代码独立。
4. 线程池
为什么要用线程池
- 控制线程数量;
- 省去创建和消耗。
常见线程池(名字记不住也没关系)
- newSingleThreadExecutor
单个线程的线程池,即线程池中每次只有一个线程工作,单线程串行执行任务; - newFixedThreadExecutor
固定数量的线程池,没提交一个任务就是一个线程,直到达到线程池的最大数量,然后后面进入等待队列直到前面的任务完成才继续执行 - newCacheThreadExecutor
可缓存线程池,空闲时回收,不够时添加; - newScheduleThreadExecutor
大小无限制的线程池,支持定时和周期性的执行线程
了解关于线程池的哪些参数?
初始线程数、最大线程数、空闲线程数。。。
(各自的作用顾名思义,让面试官觉得你懂就行了)
5. 线程安全
线程安全是什么?(理解)
线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。
实现线程安全的两种方式?
synchronized与Lock。
二者的区别是什么?
- synchronized不能中断等待;
Lock可以中断等待。 - synchronized在JVM层面实现,出现异常时可以自动释放锁定;
Lock在代码层面实现,必须在finally{}
中unLock
。 - 资源竞争不激烈时,synchronized性能优;
资源竞争激烈时,Lock性能优。
volatile关键字的作用是什么?
作用:保证可见性与一致性。
(当我们使用volatile关键字去修饰变量的时候,所以线程都会直接读取该变量并且不缓存它。这就确保了线程读取到的变量是同内存中是一致的。)
6. 死锁
什么是死锁?
两个进程各自占有一个资源,并申请对方的资源,永远阻塞。
(与数据库中的死锁对比理解)
死锁的条件?(了解)
- 互斥条件:
一个资源每次只能被一个进程(线程)使用。 - 请求与保持条件:
一个进程(线程)因请求资源而阻塞时,对已获得的资源保持不放。 - 不剥夺条件 :
此进程(线程)已获得的资源,在末使用完之前,不能强行剥夺。 - 循环等待条件 :
多个进程(线程)之间形成一种头尾相接的循环等待资源关系。
避免死锁的著名算法(了解)
银行家算法