一、谈谈什么是守护线程?
- 守护线程:为所有的非守护线程提供服务的线程;任何一个守护线程都是整个JVM中所有非守护线程的保姆;
- 守护线程依赖于整个进程而运行,哪天其他线程结束了,没有要执行的了,程序就结束了,不会理会守护线程,直接中断他;守护线程是不靠谱的,它本身的终止自己都无法控制,所以不要把io、File等重要的操作逻辑分配给它;
二、守护线程的作用?
- 举例:垃圾回收线程(GC),守护线程。当我们的线程中不再有任何线程,程序就不会再产生垃圾、垃圾回收线程无事可做,当JVM上只有GC时,就会自动离开。它始终在低级别的状态下运行 ,用于实时监控和管理系统中的可回收资源。
- 应用场景:守护线程必须为其他线程提供服务,或者程序结束时,这个线程必须正常且立刻关闭,就可以作为守护线程使用。
- thread.setDaemon(true)必须在thread.start()之前设置,否则会抛出IllegalThreadStateException异常,不能把正常运行的线程设置为守护线程。
4、java自带的多线程框架,比如ExecutorService,会将守护线程转换为用户线程,所以如果要使用后台线程就不能用java的线程池。
三、Threadlocal的原理和使用场景?
1、每一个Thread都有一个ThreadLocalMap类型的成员变量,它存储本线程中所有Threadlocal对象及其对应的值。
2、ThreadLocalMap由一个个Entry组成,Entry继承了WeakReference,一个Entry由一个ThreadLocal对象和Object构成,Entry的key是Threadlocal对象,并且是一个弱引用。当没有指向key的强引用后,该key就会被垃圾回收。
3、原理:当执行get、set方法的时候,ThreadLocal首先会获取当前线程的对象,然后获取当前线程ThreadLocalMap对象,将当前ThreadLocal对象作为key,将值储存进ThreadLocalMap对象里面。
4、由于每一条线程都含有各自私有的ThreadLocalMap容器,这些容器相互独立互不影响,因此不会存在线程安全性问题,从而也无需使用同步机制来保证多线程访问容器人的互斥性。
5、使用场景:
- 在进行对象跨层传递的时候,比如从dao层传到service层再传到web层,使用ThreadLocal可以避免多次传递,打破层次键的约束。
- 线程间数据隔离;
- 进行事物操作,用于存储线程事物信息
- 数据库连接,Session会话管理。
- Spring框架在事物开始的时候会给的那个线程绑定一个 JDBC Connection,在整个事物都是使用该线程绑定的connection为执行的数据库操作,实现了事物的隔离性,Spring框架就是用的Threadlocal来实现隔离的。
三、Threadlocal内存泄漏的原因以及如何避免?
1、内存泄漏:内存被占用无法被GC回收。
2、