一.JAVA线程的五种状态:
新建状态、准备运行状态、运行状态、阻塞状态、终止状态
1.新建(New):
这是线程的初始状态,表示线程对象刚刚被创建,还没有开始执行。
2.就绪(Runnable):
当线程被创建后,它将会进入这个状态。一旦线程调度程序将该线程放入执行队列,它就会变为此状态。此状态通常表示等待执行的具体时间点和调用start()方法的时刻是分开的。
多线程环境下,每个线程都会被分配⼀个固定长度的 CPU 计算时间,每个线程运⾏⼀会⼉就会停⽌让其他线程运⾏,这样才能让每个线程 公平的运⾏。这些等待 CPU 和正在运⾏的线程就处于 Runnable 状态。
3.运行中(Running):
当线程开始执行程序,它将在此状态运行,直到完成它当前的任务或阻塞状态出现为止。
4.阻塞(Blocked):
如果一个线程处于阻塞状态,则该线程正在等待其他线程执行特定的操作(如同步操作),此时它不能继续运行。阻塞状态通常发生在等待锁、等待条件变量、等待I/O操作等情况下。
5.等待(Waiting):
当线程处于等待状态时,它正在等待一个对象的状态改变,例如等待某个条件变量变为可用状态。
以下⽅法会让线程进⼊等待状态:
Object.wait()
Thread.join()
LockSupport.park()
6.超时等待(Timed waiting):
这是等待状态的扩展,它允许线程在指定的时间内等待某个条件变为可用状态。
以下⽅法会让线程进⼊超时等待状态:
Thread.sleep(sleeptime)
Object.wait(timeout)
Thread.join(timeout)
LockSupport.parkNanos(timeout)
LockSupport.parkUntil(timeout)
7.终止(Terminated):
当线程完成它的任务或因异常终止时,它将处于此状态。
二.ThreadLocal
场景
主要⽤途是为了保持线程⾃⾝对象和避免参数传递,主要适⽤场景是按线程多实例(每个线程对应⼀个实例)的对象的访问,并且这个对象很多地⽅都要⽤到。
原理
为每个线程创建变量副本,不同线程之间不可见,保证线程安全。使⽤ ThreadLocalMap 存储变量副本,以 ThreadLocal 为 K,这样⼀个线程可以拥有多个 ThreadLocal 对象。
实际
使⽤多数据源时,需要根据数据源的名字切换数据源,假设⼀个线程设置了⼀个数据源,这个时候就有可能有另⼀个线程去修改 数据源,可以使⽤ ThreadLocal 维护这个数据源名字,使每个线程持有数据源名字的副本,避免线程安全问题。