JUC面试题
# ThreadLocal有哪些使用场景
ThreadLocal是一种多线程隔离机制,通过多线程环境下对共享变量的副本存储,解决了线程安全问题,避免了多线程竞争加锁的开销。其使用场景包括:
线程的上下文传递
- 在处理请求的过程中保持用户特定的数据(如用户的登录信息)。通过
ThreadLocal
可以方便地在同一个线程内的不同方法调用之间共享这些数据,而不用担心线程安全问题。
- 在处理请求的过程中保持用户特定的数据(如用户的登录信息)。通过
数据库连接管理
- 在多线程应用中,每个线程可以使用
ThreadLocal
来独立管理自己的数据库连接,避免线程之间的竞争与冲突。如mybatis的sqlsession
- 在多线程应用中,每个线程可以使用
事务管理等
- 使用
ThreadLocal
可以让每个线程拥有独立的事务上下文,保证事务的隔离性。Spring 的TransactionSynchronizationManager
就使用ThreadLocal
来存储当前线程的事务资源(如数据库连接)。
- 使用
在使用ThreadLocall时,需要注意避免内存泄漏的问题。
# Java线程的生命周期
Java线程的生命周期包括6种状态(定义在Thread.State
枚举中):
- NEW(新建状态):
- 线程被创建但尚未启动。此时线程对象已经存在,但还没有调用
start()
方法。
- 线程被创建但尚未启动。此时线程对象已经存在,但还没有调用
- RUNNABLE(可运行状态):
- 一旦调用了线程对象的
start()
方法,线程就进入了RUNNABLE
状态。此时线程可能正在Java虚拟机中运行,也可能是在等待操作系统的调度来获取CPU时间片。在操作系统层面,RUNNABLE
状态对应RUNNING
(正在运行)和READY
(准备运行)两种子状态。
- 一旦调用了线程对象的
- BLOCKED(阻塞状态):
- 如果一个线程试图获取一个已经被其他线程持有的synchronized锁(即进入同步块或方法),那么该线程将进入
BLOCKED
状态。只有当前持有锁的线程释放了锁,这个线程才能继续进行。
- 如果一个线程试图获取一个已经被其他线程持有的synchronized锁(即进入同步块或方法),那么该线程将进入
- WAITING(等待状态):
- 线程进入等待状态,直到被其他线程显式唤醒。线程可以通过三种方法进入
WAITING
状态:Object.wait()
:等待其他线程调用notify()
或notifyAll()
。Thread.join()
:等待目标线程执行完毕。LockSupport.park()
:暂停当前线程。
- 线程进入等待状态,直到被其他线程显式唤醒。线程可以通过三种方法进入
- TIMED_WAITING(超时等待状态):
- 线程进入等待状态,但会在指定的时间后自动唤醒。线程可以通过四种带有超时时间的方法进入
TIMED_WAITING
状态:Thread.sleep(long millis)
:睡眠指定时间。Object.wait(long timeout)
:等待指定时间。Thread.join(long millis)
:等待目标线程指定时间。LockSupport.parkNanos(long nanos)
:暂停当前线程指定时间。
- 线程进入等待状态,但会在指定的时间后自动唤醒。线程可以通过四种带有超时时间的方法进入
- TERMINATED(终止状态):
- 线程执行完毕或因为异常退出,进入终止状态。此时线程的生命周期结束。
# 线程池如何知道线程任务的执行完成
- 线程池的isTerminated()
- 使用isTerminated()方法可以检查线程池是否已经完全终止,但需要先调用
shutdown()
方法。通常情况下,线程池不会随意关闭,因此isTerminated()
的使用场景有限。
- 使用isTerminated()方法可以检查线程池是否已经完全终止,但需要先调用
- 使用Future对象
- Future可以判断单个任务的完成状态。通过调用线程池的
submit()
方法提交任务时,会返回一个Future
对象,而Future
的isDone()
方法,可以非阻塞地检查任务是否完成。或者调用Future的get()方法可以阻塞当前线程,直到任务完成并返回结果或者抛出异常。
- Future可以判断单个任务的完成状态。通过调用线程池的
- CountDownLatch:
- 使用
CountDownLatch
同步工具,适合用于多个任务的同步,可以在开始时设置一个初始值,任务完成后调用countDown()
方法把计数器减一,主线程通过await()
等待计数器归零,表示任务完成。
- 使用
上次更新: 2025/3/31 20:10:39