目录
进程、线程的区别
一个进程中,可以有多线线程。进程负责分配内存,线程负责调度,多个线程共享一块内存
如何保证线程顺序执行
- 使用join方法,t1中调用t2的join方法,等待t2的执行完成再继续执行
- 可以使用wait notify
线程有哪几种状态
- new状态,对象创建,但是还未调用start方法
- ready状态,就绪状态,等待被cpu调度
- running状态,运行状态
- waiting状态,等待状态
- blocked状态,阻塞状态
- teminated状态,死亡状态
线程池有哪些
ForkJoinPool 分叉合并
ThreadPoolExecutor 线程池
线程池的参数(手动定义线程池7个参数)
- 核心线程数
- 最大线程数
- 空闲时间
- 空闲时间单位
- BlockingQueue 任务队列
- 线程工厂(可以自定义线程名称,方便出错时回溯)
- 拒接策略(1.抛异常 2.扔掉 3.扔掉最后一个 4.调用者线程处理)可以自定义
线程池执行过程
- 初始化线程池,当有第一个任务时,创建线程,结束后作为核心线程,一直到核心线程数满了为止
- 如果核心线程数满了,再来线程时,进入队列
- 如果队列满了,创建线程,直到最大线程数
- 如果到达最大线程数,那么执行拒绝策略
如何管理Future结果
使用CompletableFuture类管理多个Future结果
有了List为什么还要有queue
queue对于多线程提供了更多的支持,例如poll、offer、peek方法
sychronized锁升级过程
- 无锁
- 偏向锁,至于一个线程访问时
- 轻量级锁(自旋锁),等待线程少或者线程执行时间短时采用自选锁
- 重量级锁,自旋锁在10次以上或者线程过多时就会升级为重量级锁
java中有哪些锁
悲观锁(排他锁)、乐观锁(自旋锁)、共享锁、读写锁、分段锁
悲观锁:sychronized
乐观锁:AtmoicXX
读写锁:ReentrantReadWriteLock
分段锁:LongAdder、concurrentHashMap
常用的锁
- sychronized
- ReentractLock
- countDownLatch 计数器
- CyclicBarrier 栅栏
- Phaser 用于阶段执行
- Seamphore 信号灯
- Exchanger 交换器
- LockSupport
sychronized与ReentractLock的区别
锁 | 是否需要手动释放锁 | 是否语言自带 | 底层实现 | 扩展性 |
---|---|---|---|---|
sychronized | 自动释放锁 | 是 | 锁升级 | 无 |
ReentractLock | 手动释放锁 | 否 | cas | 支持自定义condition,更加灵活 |
ValHandler
jdk9自带,指向对象的引用,可以通过这个对象,来完成cas操作
AQS内部原理
使用state+双端队列实现
每重入一次,state+1,当state为0,即无锁
如果是公平锁,新加入的线程,排到队列末尾,如果是非公平锁,新加入的线程直接参与争抢。
volatile实现细节
-
字节码层面 ACC_VOLATILE
-
JVM层面:
StoreStore
volatile写操作
StoreLoadLoadLoad
volatile读操作
LoadStore -
os和操作系统层面 lock指令
volatile依赖硬件以及操作系统,不同的jvm有不同的实现
synchronized实现细节
- 字节码层面 ACC_SYNCHRONIZED
monitorenter monitorexit - jvm层面 c/c++调用操作系统提供的同步机制
- os和操作系统层面 lock指令