【Java八股-第四期】并发 - Java基础
提纲:
基础八股知识🔥
并发三要素
原子性
可见性
有序性
线程
定义
创建线程的方式
相关方法
解决并发问题
同步
悲观锁
乐观锁
异步
面试八股真题🎈
1、说说Java中实现多线程有几种方法
2、采用实现Runnable、Callable接口的方式创建线程的优缺点
3、采用继承Thread类的方式创建线程的优缺点
4、如何停止一个正在运行的线程
5、notify()和notifyAll()有什么区别
6、sleep()和wait() 有什么区别
7、volatile 是什么?可以保证有序性吗?
8、Thread 类中的start() 和 run() 方法有什么区别?
9、为什么wait, notify 和 notifyAll这些方法不在thread类里面
一、基础八股知识点
1. 并发三要素
-
原子性
-
可见性
-
实现方法:
-
1.volatile
-
2.final
-
3.syn修饰
-
-
-
有序性
-
体现在线程优先级上
-
2.线程
-
定义:线程是 cpu 调度的最小单位,同一个 Java 进程中的线程共享进程中的内存资源
-
创建线程的方式:
-
让类继承 Thread,实现 run 方法,通过调用 start 方法启动线程并执行 run 方法
-
实现 Runable 接口,作为任务对象传给 Thread 或线程池,调用 Thread 或线程池的run 和 excute 方法执行 Runable 接口的 run 方法
-
实现 Callable 接口,方法与 Runable 接口一样,可以使用 FutureTask 线程执行并得到返回结果
-
使用 ThreadPoolExcute 自定得到线程池,也可以使用 Excutors 获取 JDK 中一些提前定义好的线程池,调用 excute 方法传入 Runable 任务对象来执行
-
-
不同方式创建线程的区别:
-
实现Runnable和Callable接口。是用这种方法创建的线程还可以继承其他类;
-
继承Thread类。用法简单但是不能再继承别的类;
-
Callable重写call方法,Runnable重写run方法,call方法可以抛异常,run方法不可以,Callable执行后有返回值,Runnable没有
-
-
相关方法:
-
static 静态方法
-
currentThread:获取当前正在执行的线程
-
interrupted:获取并重置目标线程的打断标记
-
yield:线程主动交出时间片,进入 Runable 状态
-
sleep:线程主动交出时间片,进入 Time_Wait 状态
-
-
非静态方法
-
isInterrupted:获取线程的打断标记,不会重置
-
interrupt:打断线程,若被打断的线程正在 sleep/join/wait 会抛出异常
-
join:等待另一个线程执行完毕
-
-
3.解决并发问题
-
同步
-
悲观锁
-
Sychronized 锁
-
特点:可重入、互斥、非公平
-
-
Lock 锁
-
-
乐观锁
-
unsafe 的 CAS,利用的是操作系统的原语,从操作系统层面讲,原语已经是无法再细分的指令
-
-
-
异步 —— ThreadLocal
-
ThreadLocal 表示线程本地的变量,可以通过将共享变量分成多份副本,每个线程在自己的副本上进行操作
-
在将变量副本进行存储时,以 ThreadLocal 为 Key,变量为 Value 存储,通过 currentThread方法获取当前线程,并将其存储在线程中的 TreadLocalMap 中,存储 K-V 的 Entry 继承自WeakReference,是弱引用对象,并且与 HashMap 不同的是,采用开放定址法解决哈希冲突的问题
-
使用场景
-
在 Controller 中调用 Service 的方法时,可以将参数保存在 ThreadLocal 中,在 Service 中获取当前线程的方式获取参数,然而并没有什么用,还要手动 remove 删除变量防止内存泄漏,通常还是采用显示传参的方式
-
用来存放用户登录的 Token 信息,异步调用的方法慎用
-
S
-
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
【📫专栏目录在最底部📫】 - 本专栏适合于JAVA已经入门的学生或人士,有一定的编程基础。 - 本专栏特点: 本专刊囊括了JAVA、Spring、计算机网路、操作系统、计算机网络、MySQL、算法与数据结构、中间件等一系列知识点,总结出了高频面试考点(附有答案),事半功倍,为大家春秋招助力。 - 本专栏内容分为五章