1.进程和线程的区别 ,进程如何通信
进程是系统运行的基础单位,进程与进程之间相互不影响。
线程是独立运行的最小单位,一个进程包含多个线程公用同一个系统资源,线程之间相互影响。
进程之间通过管道、内存共享、信号量机制、消息队列通信
2.什么是线程上下切换
一个线程被剥夺cpu使用权,切换到另一个线程执行。
3. 什么是死锁
死锁指的是多个线程执行过程中,争夺一个资源导致相互等待的僵局。
4. 死锁的必要条件
- 互斥条件:一个资源同时只能被一个线程读取
- 不可抢占条件:不能强行剥夺其他线程占有的资源
- 请求和保持条件:请求其他资源的同时对自己手中的资源不放
- 循环等待条件:在相互等待资源的线程中,形成了闭环。
想要预防死锁,只需要破坏其中一个条件即可,比如使用定时锁、尽量让线程使用相同枷锁顺序,还可以使用银行家算法预防死锁。
5.Synchronized和lock的区别
- synchronized是关键字,lock是一个
- synchronized发生异常会自动释放锁,lock发生时需要手动释放锁
- synchronized是可重入锁,非公平锁、不可中断锁,lock的ReentrantLock是可重入锁、可中断锁,可以是公平锁也可以是非公平锁
- synchronized的底层是JVM通过监视器实现的,Lock是通过AQS实现的
6.什么是AQS锁?
AQS的原理是,AQS内部有三个核心组件,一个是state代表加锁状态初始值为0,一个是获取到锁的线程,还有一个阻塞队列。当有线程想获取锁时,会以CAS的形式将state变为1,CAS成功后便将加锁线程设为自己。
7. volatile是什么?
volatile是Java虚拟机提供的轻量级同步锁机制
保证了可见性、有序性,不保证原子性。
被volatile关键字修饰的变量,如果值发生了变化,其他线程立刻可见,避免出现脏读现象。
8. 线程的创建方式
- 实现Runnable接口重写run方法。
- 继承Thread调用run方法。
- 实现Callable接口,带返回值
- 使用线程池创建线程。
9. java中垃圾回收的方法有哪些
标记清除算法:标记不需要回收的对象,垃圾回收时清除没有被标记的数据,fullGC
标记整理算法:与标记清除算法类似,但是在标记之后,将存活对象向一端移动,然后清除边界外的垃圾对象;
复制算法:将内存一分为二,只使用一块,当垃圾回收时,将不清理的数据复制到另一块空间,然后清除原来的空间;
10. 什么情况下内存会溢出
堆溢出:
- 当对象一直创建不被回收时
- 加载的类越来越多时
- 虚拟机栈的线程越来越多时
栈溢出:
- 方法调用次数太多,多数因为递归使用不当造成的
11. JVM中有哪些引用
- 强引用:new的对象内存溢出也不会回收
- 软引用:只有内存不足时才会回收
- 弱引用:每次垃圾回收时都会回收
- 虚引用:不许配合引用队列使用,一般用于监控垃圾回收
12. ThreadLocal原理
为每个线程都创建一个副本,为了保证线程安全不同的线程之间不可见,每个线程都维护了一个map对象,key为ThreadLocal实例 ,value为要保存的副本,因为key为弱引用,而value为强应用,所以每次cg时key都会回收,value不会回收,所以每次用完之后可以删除value或者使用static修饰TreadLocal,可以随时获取value。
13.CG的回收机制和原理
CG的目的是为了实现内存的自动释放,使用可达性分析法判断是否可回收,采用了分代回收思想
将堆分为新生代和老年代,新生代使用复制算法,老年代使用标记整理法,当新生代内存不足时会发生MinorGC,老年代内存不足会发生FullGC
14. GC如何判断对象可以被回收?
- 引用计数器法:对对象添加引用计数器,引用值为0时回收
- 可达性分析法:从GCRoot开始往下搜索,搜索的路径叫做引用链,若没有引用链就会回收。
15. 线程的声明周期是什么?
线程有五种状态:新建、就绪、运⾏、阻塞和死亡状态
- 新建状态(New) : 新创建了⼀个线程对象
- 就绪状态: 线程对象创建后,其他线程调⽤了该对象的 start ⽅法。该状态的
- 线程位于可运⾏线程池中,变得可运⾏,等待获取CPU的使⽤权
- 运⾏状态(Running) : 就绪状态的线程获取了 CPU,执⾏程序代码
- 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使⽤权,暂时停⽌运⾏。直到
- 线程进⼊就绪状态,才有机会转到运⾏状态
- 死亡状态(Dead) :线程执⾏完了或者因异常退出了 run ⽅法,该线程结束⽣命周期