Java学习-多线程-01
Java 学习-多线程-01
1.线程的生命周期、线程有几种状态
生命周期:
- 初始化(NEW)
- 运行(RUNNABLE)
- 阻塞(BLOCKED)
- 等待(WAITING)
- 有时限等待(TIMED_WAITING)
- 死亡(TERMINATED)
线程状态:
有 6 个状态:
1 | |
因为阻塞(BLOCKED)、等待(WAITING)、有时限等待(TIMED_WAITING)三种状态都是阻塞状态,没有 CPU 的使用权,所以可以用下图表示:

2.sleep()、wait()、join()、yield()区别

sleep
- sleep 方法是 Thread 的静态方法
- sleep 使当前线程进入阻塞状态,在指定时间内不会执行
- sleep 期间,不会释放锁
wait
- wait 方法是 Object 的非静态方法
- 在其他线程调用 notify 或者 notifyAll 方法前,线程释放当前所占用的锁标识
- 当前线程必须拥有当前对象锁
- wait 和 notify 必须在 synchronized 代码块中使用
yield
- 暂停当前线程对象
join
- join 方法是 Thread 的静态方法
- 等待调用 join 方法的线程结束,在继续执行
3.对线程安全的理解
当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方法进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那么这个对象时线程安全的。
4.Thread、Runable 的区别
- Thread 的实现方式是继承
- Runable 的实现方式是实现接口
- Thread 实现了 Runable 接口,并进行了扩展
5.对守护线程的理解
守护线程是运行在后台的一种特殊进程。它独立于控制台,并且不会影响控制台的状态。守护线程的主要作用是负责系统的内存管理,以及系统的安全措施。
1 | |
6.ThreadLocal 的原理和使用场景
ThreadLocal 是什么
ThreadLocal 的作用是给线程提供一个 作用域是整个线程,生命周期是线程存活时期的 **线程局部变量**。每个线程都可以通过 ThreadLocal 对象来访问属于自己的数据。总的来说有以下两个特点:
- 线程内共享,线程运行到那里了都可以使用 ThreadLocal 中存储的变量
- 线程间隔离,线程只能看到自己存储在 ThreadLocal 中的变量,其他线程不能访问
ThreadLocal 的原理
ThreadLocal 的原理是:在线程中存储一个 ThreadLocal 对象,每个线程都有自己的 ThreadLocal 对象,每个线程都有自己的 ThreadLocal 对象中的变量。
void set(T value)
set 方法设置当前线程中 threadLocal 变量的值,该方法的源码为:
1 | |
value 值被存放在 ThreadLocalMap 里,由每个 Thread 各自维护,每个 Thread 都有自己的 ThreadLocalMap,每个 Thread 都有自己的 ThreadLocalMap 中的变量。
ThreadLocal 的使用场景
- ThreadLocal 不是用来解决共享对象的多线程访问问题。
- ThreadLocal 是让每个不同的线程拥有属于自己的数据容器( ** ThreadLocalMap ** )
1 | |
7.ThreadLocal内存泄漏的原因,如何避免
内存泄漏的原因
ThreadLocal 数据实际上是存放在其内部类 ThreadLocalMap里面。 ThreadLocal 的get、set、remove方法,实际上是调用 ThreadLocalMap 的 getEntry、setEntry、removeEntry 方法。
ThreadLocalMap内部通过一个Entry类型的table数组来维护数据。
Entry中的key是弱引用,当threadLocal外部强引用被置为null(threadLocalInstance=null),那么系统 GC 的时候,根据可达性分析,这个threadLocal实例就没有任何一条链路能够引用到它,这个ThreadLocal势必会被回收,这样一来,ThreadLocalMap中就会出现key为null的Entry,就没有办法访问这些key为null的Entry的value,如果当前线程再迟迟不结束的话,这些key为null的Entry的value就会一直存在一条强引用链:Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value
永远无法回收,造成内存泄漏。
避免
每次使用完线程数据,都要调用一次ThreadLocal.remove()方法手动删除Entry对象
8.并发、并行、串行的区别
- 串行:时间上不可重叠发生,前一个任务还没完成,下一个任务只能等待;
- 并行:时间上可以重叠,多个任务在同一时刻互补干扰的同时执行;
- 并发:多个任务在同一时期内同时发生执行;
9.并发的三大特性
- 原子性:
原子性值指一个操作是不可分割、不可中断的要么全部执行并且执行的过程不会被任何因素打断,要么全部不执行。 - 可见性:
可见性指的是一个线程修改了某一个共享变量时,其他线程能够立即知道这个修改。 - 有序性:
有序性指的是一个线程的执行代码,从前往后执行,单线程下可以认为是有序的,但是并发时可能发生指令重排。
10.volatile
- 保证变量的内存可见性
- 禁止volaite变量与其他变量的指令重排序
PS:重排序:为优化程序性能,对原有的指令执行顺序进行优化重新排序。重排序可能发生在多个阶段,比如编译重排序、CPU重排序等。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!