文章目录
- 0.线程基础知识
- 1.线程包括哪些状态?状态之间是如何变化的?
- 2.wait和sleep方法的不同?
- 1.JMM内存模型
- 2.CAS
- 1.实现原理
- 2.ABA问题
- 3.AQS
- 1.什么是AQS?基本工作机制?
- 2.AQS和synchoronized的区别?
- 3.AQS是公平锁还是非公平锁?
- 4.synchoronized关键字
- 1.synchoronized基本实现原理?
- 2.synchronized锁升级的过程?
- 3.**synchronized和reentrantLock区别?**
- 4.ReentrantLock的实现原理?
- 5.请谈谈你对volatile的理解
- 5.线程池
- 1.线程池的核心参数
- 2.线程池的执行原理
- 3.线程中有哪些常见的阻塞队列?
- 4.如何确定核心线程数?
- 5.线程池的种类有哪些?
- 6.为什么不建议使用Executor创建线程池?
0.线程基础知识
1.线程包括哪些状态?状态之间是如何变化的?
2.wait和sleep方法的不同?
1.JMM内存模型
线程分为所有线程共享的主内存和私有线程的工作内存,在修改数据的时候会先获取数据到工作内存中,在修改后再设置到主内存。
2.CAS
1.实现原理
compare and swap的缩写,比较并交换,包含三个操作数,原始值V,预期值A,新的值B,当AV相同时则修改内存值为B,否则就什么都不做或者重试,这种重试机行为就称之为自旋。
2.ABA问题
举个例子,假设原始值是A,此时线程2判断原始值A跟期望值A是相同的,然后线程1将A变成B然后再变成A,此时线程2就正常将A变成B了,这样就会导致ABA问题。采用一个AtomicSampedReference来解决即可,每次更改之后版本都更新,这样假设原始版本是1,那么ABA之后版本就是3了。
3.AQS
1.什么是AQS?基本工作机制?
AQS就是抽象队列同步器,内部维护了一个的双向队列,还有一个属性state默认是0,线程通过CAS操作去修改这个state,如果成功修改为1,则相当于获取到了资源,而其他没有抢到资源的线程,都会放到双向队列中去排队。
2.AQS和synchoronized的区别?
3.AQS是公平锁还是非公平锁?
4.synchoronized关键字
1.synchoronized基本实现原理?
同步方法:常量池中会有一个acc_synchoronized标志,一个线程在进入方法之前会先判断有没有这个标志,如果有,则需要先获得监视器锁,然后开始执行方法,需要注意的是,如果在方法执行过程中出现了异常,但是没有处理,在抛出异常时,监视器锁会被释放。
同步代码块:使用monitorenter和,monitorexit两个指令实现,monitorenter就是加锁,monitorexit就是解锁。这个锁是可重入的,就是内部有一个计数器,同一个线程连续获取锁,这个计数器数量就加一,释放一次锁,数量减一,只有当数量为0时,其他的线程才可以获取锁。
2.synchronized锁升级的过程?
1. 无锁状态
• 对象刚创建时,对象头的 Mark Word 处于无锁状态,此时对象没有被任何线程锁定。
• Mark Word 中存储的通常是对象的哈希码、分代年龄等信息。
2. 偏向锁(可重入)
• 当第一个线程尝试获取锁时,JVM 会将对象头的 Mark Word 更新为偏向锁状态,并将偏向的线程 ID 存储在 Mark Word 中。
• 偏向锁的特点是可重入,如果同一个线程再次进入同步块,不需要做任何同步操作(例如 CAS 操作),直接执行即可,极大地提高了性能。
• 锁撤销:如果其他线程尝试获取该锁(即尝试将 Mark Word 中的线程 ID 更改为自己),偏向锁会被撤销。撤销时,会触发轻量级锁的过程。
3. 轻量级锁(CAS)
• 锁升级到轻量级锁的条件:当偏向锁被撤销后,JVM 会使用 CAS 操作尝试将 Mark Word 的内容替换为指向线程栈中锁记录(Lock Record)的指针。如果 CAS 成功,则表示轻量级锁获取成功。
• 锁膨胀:如果多个线程反复竞争锁,导致自旋失败次数达到一定阈值,轻量级锁会膨胀为重量级锁。
4. 重量级锁(Heavyweight Locking)
• 锁升级到重量级锁的条件:当自旋失败次数过多,或者线程数过多,JVM 会将轻量级锁膨胀为重量级锁。此时,Mark Word 中的内容会变为指向Monitor 对象的指针。