JUC
介绍一下JUC下的锁(如何使用及应用场景)
线程
- 什么是进程:
- 特征
- 什么是线程:资源
-
为什么多线程,什么使用用单线程,什么时候多线程,什么条件下多线程快。
-
进程和线程的对比:
- 进程如何通信,每种通信存放的介质。|| 线程的通信,几种方式。join
- 进程和线程的区别,在JVM层面的体现
- 一个进程最多有多少线程?
-
创建线程的方式/方法
- Thread(用哪个方法,执行先后,缺陷)
- runnable(实现接口,优点) 和thread的关系
- callable(返回值,三个步骤最后包装成线程对象)
- callable和runnable异常信息
- submit和excute
-
线程方法:
- run和start区别
- 线程暂停的方法?yield会阻塞吗,sleep和yield
- 线程sleep和wait的区别,会释放对象锁吗?分别什么时候使用?wait用于通信。
- 为什么sleep方法不需要申请释放锁
- wait() 的底层原理
- join,线程的等待用于同步。
- 新建 T1、T2、T3 三个线程,如何保证它们按顺序执行?通过join
- interrupt,异常处理:
- 哪些方法会阻塞,打断阻塞线程和正常线程的去区别。
- 并发的时候,如果有其它线程调用interrupt进行中断它会立即中断吗?
- 打断,park线程
终止模式,。—两阶段终止- 如何终止线程(三个方法)
- 为什么不建议使用 stop() 停止线程
-
线程原理:
- 线程上下文切换过程:哪些情况,用户态和内核态的区别?用户态和内核态之间的切换会影响到线程的执行效率,真正慢的点在哪里?
- 线程模型:和操作系统线程对应,内核调度。
- 线程的调度:
- 什么是协程:协程是什么,如何判断多少协程数是一个最优的选择?和cpu内核之间有什么关联?协程之间的调度是怎样的? 和内核协程的对应。
-
线程状态-生命周期:
-
线程的生命周期状态流程? start方法。线程怎么唤醒的
- 各种状态的转换
- 和操作系统线程的对比
-
用什么命令可以查看进程和线程:
- windows
- 进程查看和杀死命令
- linux
- 看进程,看线程
- Process status --ps
- 查看线程执行时间呢
e
是--everyone
的缩写,表示显示所有用户的进程而不仅仅是当前用户的进程。而f
是--full
的缩写,表示显示完整的进程信息,包括进程之间的父子关系(进程树)以及其他详细信息。-f
选项用于显示完整的进程信息,-T
选项用于显示进程的线程信息top
是一个命令行实用程序,用于监视系统的实时进程和系统性能。- 如何查看有多少线程。
- 查看java线程栈
- windows
-
-
同步
线程的同步和异步:
-
临界区和临界资源:
- 阻塞式和非阻塞式解决方法:
- synchronized:优缺点,synchronized会发生死锁吗为什么会,什么时候死锁
-
synchronized —同步锁
-
是什么锁:悲观非公平
-
synchronized锁在什么情况下会释放,空指针或者超时会释放锁吗?
-
synchronized 的使用
-
特点
-
怎么使用
-
同步代码块,锁的对象
-
同步方法:
-
线程八锁–看对象
-
-
synchronized加在实例方法上,通过两个对象同时访问可以吗
- 作用在类方法
- synchronized可以保证原子性吗,可以
- synchroized什么时候释放锁
-
synchronized的作用域
-
-
synchronized的底层原理
-
Monitor
- 是什么,存在哪,有什么用,谁提供怎么实现的
- 工作流程
- owner//EntryList BLOCKED(双向链表),
- 说说你对 Java 里
monitor
的理解?monitor
是操作系统里的概念,你能讲讲它在 Java 里的实现吗?
-
字节码
- 异常 try-catch 机制,确保一定会被解锁
-
happens-before是干嘛的 synchronized的happens-before原则是哪一条
-
-
锁的升级:
-
有哪些锁,锁升级的过程是从哪个锁到哪个锁。各个锁的作用
-
锁升级过程,对synchronized 进行升级。synchronized一定是悲观的吗,有没有锁升级的过程
-
偏向锁:
- 偏向状态,记录thread_id
- 如何撤销,三种方法
-
轻量级锁:
-
操作流程
-
上锁失败的两种可能性:
- 失败的后果。
-
锁膨胀:
- 在轻量级锁加锁有竞争时。
- 如何升级,流程
-
什么情况下会达到重量级锁
-
什么情况时候适合用轻量级锁,重量级锁 适用的场景
-
-
涉及到对象头怎么包含
-
-
锁的优化:
- 自旋锁-用在哪-优缺点,自适应自旋锁,原理
- 锁消除(原理)、锁粗化、
-
活跃性
- 死锁
- 条件/如何检测,如何查看死锁。
-
-
wait-ify
- wait/notify/notifyAll,内部做了什么事情?
- 挂起和阻塞的区别
- 和sleep的区别
- wait要进入EntryList 竞争
- wait/notify/notifyAll,内部做了什么事情?
-
线程安全分析:
-
同步模式
-
用过异步没(用过completable future)用这个有没有要注意的地方- CompletableFuture,thenApply 方法,是在主线程还是在子线程执行的;
- CompletableFuture用线程池了吗
- future 是任何时候都可以取到数据吗?
- future 的底层
- java如何实现异步非阻塞调用
内存
-
JMM是什么:作用是什么
-
线程/线程方法中定义的一些变量是放在堆上面还是栈上面?
-
内存交互操作都是原子的。
- 在java里面,有哪些机制保证原子性、可见性、有序性。
- 什么是可见性,为什么有可见性问题,如何修改
- 什么是原子性
- 什么是有序性
- 三大特性存在的问题
- 在java里面,有哪些机制保证原子性、可见性、有序性。
-
工作内存和主内存对应操作系统中的什么
-
-
Cache缓存机制:
-
内存屏障
-
volatile
-
三大特性,不能保证哪个
-
synchronized 和volatile区别
- 如何保证两个特性
-
如何禁止指令重排序,为什么指令要重排序,为什么有可见性问题。
-
底层原理
-
缓存一致
-
内存屏障
- 两个作用
-
-
无锁
有哪些无锁方法
-
CAS
- 什么是 CAS,CAS锁底层实现原理
- cas的特点,cas的缺点
- cas乐观锁和普通悲观锁的区别,
- 什么时候用cas什么时候用到锁
- 什么是多读场景什么是多写场景?提到了秒杀系统
- java里有哪些地方用到吗
- (cas-并发计数器,乐观锁实现,自旋锁实现。)
- 什么是 CAS,CAS锁底层实现原理
-
Atomic原子类
- 常见方法
- 原理- 哪两个组合
- 后面的略过
- 如果一堆数据重的订单信息在多线程的场景下用什么数据类型
- AtomicInteger原子类
-
Adder
- 略过
-
ABA问题
- 可通过什么方法解决
-
final -
- String为什么线程安全
-
Local重点:
-
基本介绍:
-
为什么要用threadlocal,作用
- 用什么修饰
- 放在哪
-
和synchronized的区别
-
-
基本使用:
- 常用的方法,适用的场景
- 有什么特点
-
底层实现原理:
-
底层结构
-
JDK8以前,存在什么问题,如何解决
-
JDK8以后呢:
- 是什么创建了map
- Key和value是什么
-
前后对比
-
-
成员方法:
- 怎么保证并发安全/
- get/set方法–都是间接调用的threadLocalMap的方法,先通过thred获取对应的threadLocalMap,然后threadlocal找到entry
-
-
LocalMap
- 都是独立实现的
- Thread对应的存储结果就是threadLocalMap
- threadLocalMap的remove方法了解吗?
- 清理方式:了解
-
为什么内存泄漏,怎么解决的内存泄漏;
- 看下黑马, 内存泄漏和内存溢出的区别
-
变量传递问题:
- 普通的线程变量可以在线程间传递吗?如果在A线程中启动一个子线程,那么子线程可以访问父线程中的变量吗?如果这个变量是ThreadLocal,可以访问到吗?
- 要继承
-
ThreadLocal 中维护的队列,调用的深度越来越深会怎么样?ThreadLocal 有一次调用了异步线程,数据能接上吗?如果想要数据能够接上该怎么做?怎么去通过线程对象拿到 ThreadLocal 对象?ThreadLocal 的 LRU 过程是什么样的?
-
3.1底层原理 3.2内存泄漏的场景 3.3为什么虚引用了还要remove 3.4父线程的ThreadLocal子线程可以用吗 3.5IheritableThreadLocal原理 3.6线程池里的线程能用IheritableThreadLocal吗
-
ThreadLocal中用的锁。
-
ThreadLocal在什么场景下使用会出现问题?如何解决?
-
线程池
-
基本概述:
- 为什么要使用线程池
- 作用和优点:
- 缺点:
-
阻塞队列:
-
基本介绍:
- 线程池的队列分为哪些?可以使用无界对列吗-可以但得注意?
- 为什么要设计一个阻塞队列?
- BlockingQueue是如何实现延迟能力的呢?
- 假如我线程池里有一个线程,抛出了异常,没有处理导致线程挂掉了,线程池的线程数会减少吗?
-
核心的方法
-
线程池中有哪些常见的阻塞队列
- 链表队列和同步队列源码–略过
-
为什么不先创建临时线程而是先放进阻塞队列?
-
阻塞队列的线程安全性
-
4.1阻塞队列 4.1数组有界阻塞队列和链表无界阻塞队列哪个性能好 4.2底层怎么实现的 4.3非核心线程是怎么销毁的 4.4非核心线程提交策略
-
-
线程池的操作:
-
线程池的类
-
创建方式:
-
即如何获取线程池对象
-
Executor
-
ThreadPoolExecutor 需要的参数,核心参数是什么
- 什么时候会触发拒绝策略。拒绝策略有哪些?
- 驱逐算法
-
工作原理,整个流程
- ThreadPoolExecutor 中提交任务后的执行步骤?
- 在一个线程池中,包含了5个核心线程、队列长度为500、以及100个非核心线程的情况下,线程池的执行过程
-
-
Executors
- 线程池的种类有哪几种,分别为什么。
- 线程池扩容的策略(如果突然新来很多任务)
-
开发要求:
- 默认的线程池会出现什么问题
- 线程池的核心线程数设置为多少合适,io密集型任务和cpu密集型选择线程数 ,为什么这么选?
- 线程池任务的CPU执行时间是a,IO执行时间是b,CPU有N个核心,问如何设置线程数量
- 核心线程和非核心线程的区别
-
-
提交,关闭,异常,略过。
- 假如我想在线程池里优雅的捕获异常,而不是依托线程池的能力,应该怎么做?
-
-
工作原理:
-
ThreadPoolExecutor怎么存状态和数量
- 线程池如何监控状态,
-
成员属性:
- 成员变量: allowCoreThreadTimeOut
- 核心线程可以回收吗,怎么回收流程是什么
- 成员变量: allowCoreThreadTimeOut
-
成员方法:
- 运行方法中:keepalivetime怎么工作,源码。
- 请求的平均延迟为 3ms,最大延迟为 5ms,则 keepAliveTime 设置为多少合适
-
-
其他:
-
还知道哪些池化技术
-
线程池设计用到什么类
-
实现过线程池吗?讲讲具体实现 自己实现线程池要注意哪几点
-
-
线程池的使用场景,见ppt。
-
使用线程池,那么如果有很多请求打过来,装满了线程池的阻塞队列,执行拒绝策略造成很多请求超时,怎么处理?
-
平常经常用到线程池,业务中经常用Trace ID跟踪线程的运行路径,那复用线程池中的线程这个TraceID会出问题嘛 可以了解一下Zipkin,阿里云的SOFATracer
同步器
-
AQS
-
AQS和Synchronized的区别
-
核心思想:AQS底层数据结构以及原理
-
AQS也用了CAS
-
AQS如何实现抢占式和非抢占式锁
-
AQS如何实现公平锁和非公平锁,AQS队列为空时线程加入队列发生什么。
AQS内部逻辑
-
-
ReentrantLock
- ReentrantLock是Lock核心的一个接口
- synchronized 和reentrantlock有什么区别
- synchronized 可冲入吗
- 如果发生异常,synchronized会释放锁吗?为什么?
- 锁的使用:
- JUC中的new ReentrantLock().lock()大概做了什么?
- 公平锁:
- ReentrantLock的公平锁和非公平锁优缺点
- 说说公平锁和非公平锁。非公平锁会导致有线程长时间阻塞,java里面有机制保证线程不会长时间阻塞吗
- 可重入:
- reentrantlock可重入的意思,有不可重入的吗
- 可重入锁性能好在那
- 锁超时:
- 用try/finally 获取ReentrantLock 锁,可以让finally超时释放锁?
- 条件变量:
- 多线程条件变量的作用
- ReentrantLock的底层
- lock,reentrantlock和sychronized在性能上有什么区别?
- 和Aqs有关的是什么设计
-
countdownlanch
- 使用和原理
- countdownlatch/信号量 如何实现()?可以复用吗?信号量可以复用,这个是如何实现的?
- 信号量可以用来当锁用吗。信号量当锁是能防止指令重排问题吗,能够保证数据的可见性吗
- countdownlatch和cyclicbarrier的区别
-
semaphore
- 如何控制某个方法允许并发访问线程的数量
- CountDownLatch、CyclicBarrier、Semaphore什么时候用的
并发包:
-
ConcurrentHashMap --同时看ppt
-
看下源码
-
并发集合
- 集合对比:
- hashmap、hashtable、ConcurrentHashMap
- ConcrrentHashmap和Hashtable加锁的区别?
- 为什么性能更好
- concurrenthashmap的工作流程
- hashmap、hashtable、ConcurrentHashMap
- 并发死链问题
- 集合对比:
-
成员方法:
- put怎么并发安全的。
- 扩容: 扩容,segment会变吗? 扩容是怎么保证线程安全的。如果一个ConcurrentHashMap在被多个线程操作,在进行扩容操作时会有几个线程在处理
- 获取方法get,ConcurrentHashMap读操作原理一定能读到最新的数据吗
-
JDK7原理
- 分段锁具体底层怎么实现的,分多少段(segment会变吗),每个段里多少个内容
- 1.8之前ConcurrentHashMap支持多少线程同时操作
-
1.8之后的优化
-
原理:
- reentrantlock,synchronized,cas
- 已经用了synchronized,为什么还要用CAS呢,1.8
- 怎么实现的细粒度操作
- 为什么能并发,
-
- synchronize和lock介绍,同步代码块和Lock区别,同步代码块和lock的优缺点和适用场景
- 项目哪里用了多线程, 见ppt
- java多线程使用过哪些类或者工具
- 死锁产生的条件,如何用命令查看死锁,见ppt
- 死锁产生的本质,见ppt
- 线程a调用线程b,线程a是什么状态,如果没有数据传输呢
- 两个线程抢占一条数据怎么解决
- 在多线程这块,你在使用Java容器的时候是怎么用的,用Map举个例子
- Java开一个线程的内存开销是多少