多线程
2024-03-12 11:18:58 2 举报
AI智能生成
多线程学习整理
作者其他创作
大纲/内容
线程池
ThreadPoolExecutor
参数理解
corePoolSize
核心线程数
maximumPoolSize
最大线程数
keepAliveTime
除过核心线程数之外的线程消亡等待时间
unit
线程消亡等待时间单位
workQueue
任务队列
threadFactory
线程工厂
RejectedExecutionHandler
线程数达到最大值,任务队列也饱和时候,如何拒绝新到来的任务(拒绝策略)
拒绝策略
AbortPolicy
默认的拒绝策略就是AbortPolicy。直接抛出异常
CallerRunsPolicy
在任务被拒绝添加后,会调用当前线程池的所在的线程去执行被拒绝的任务
DiscardPolicy
直接抛弃被拒绝的任务
DiscardOldestPolicy
直接抛弃任务队列中未执行时间最久的任务
源码理解
创建线程种类
newFixedThreadPool
创建一个可重用固定线程数的线程池
newCachedThreadPool
可根据需要创建新线程的线程池
newSingleThreadExecutor
返回一个线程池,只有一个线程
newScheduledThreadPool
给定一个延迟后,可以运行命令或者定期执行。
使用
Executors
ThreadPoolExecutor
锁
悲观锁
包括synchronized,可重入锁
乐观锁
无锁,自旋锁,cas
cas
实现原理
1.从内存中读取原始变量
2.进行计算,得到新的值
3.使用缓存中的值和原始变量进行比较,如果一致则替换内存中的值,
如果不一致则再次读取内存中的值进行计算,直到替换成功
2.进行计算,得到新的值
3.使用缓存中的值和原始变量进行比较,如果一致则替换内存中的值,
如果不一致则再次读取内存中的值进行计算,直到替换成功
问答
cas操作本身就是原子性?
cas底层逻辑,判断是否为多核处理器,如果是多核处理器,
则进行lock cmpxhp操作,直接操作os
则进行lock cmpxhp操作,直接操作os
cas ABA问题
对修改变量进行添加版本控制,每次修改,版本控制进行+1
锁升级
锁升级流程
偏向锁-->轻量级锁-->重量级锁 (偏向锁和重量级锁都是用户态,重量级锁属于内核态)
锁升级过程
偏向锁如果有一个线程竞争就升级为轻量级锁
轻量级锁如果有线程自旋超过10次就升级为重量级锁或者自旋线程数超过cpu核数一半(1.6之后由jvm控制)
锁升级图片
问答
为什么有自旋锁还需要升级为重量级锁?
自旋锁是消耗CPU资源,如果锁时间较长或者自旋线程多,CPU会被大量消耗,
重量级锁有等待队列,所有拿不到锁的线程进入队列等待,不需要消耗CPU
重量级锁有等待队列,所有拿不到锁的线程进入队列等待,不需要消耗CPU
偏向锁是否一定比自旋锁效率高?
不一定,在明知道有多线程竞争条件下,
偏向锁肯定会涉及到锁撤销,这时候直接使用自旋锁
偏向锁肯定会涉及到锁撤销,这时候直接使用自旋锁
JVM启动过程,会有很多线程竞争,所以默认情况时不打开偏向锁,偏向锁默认启动时间延迟4秒
线程
概念
进程
在计算机中,我们把一个任务成为一个进程
线程
在一个进程中会存在一个或多个子任务,我们把种子任务成为一个线程
线程的创建
继承Thread
实现Runnable方式
实现Callable
lambda表达式
线程池方式
线程的状态
NEW
RUNNABLE
TERMINATED
BLOCKED
WAITING
TIME_WAITING
线程状态转换
线程状态变迁图
线程状态转换方法
start() 启动一个线程
wait() 等待一个线程 notify() 通知阻塞线程继续执行
join() 在A线程调用B.join()方法,是A线程等待B线程结束,然后再继续执行A线程的方法
wait(time) 等待一定的时间,然后继续执行线程方法
sleep(time) 等待一定的时间,然后继续执行线程方法
LockSupport.park() 等待一个线程
LockSupport.unpark(Thread) 唤醒一个线程
wait()和Sleep() 区别
● sleep是Thread类静态方法--wait是Object类方法
● sleep常用于线程暂停---wait常用于线程间交互
● sleep()不释放锁,wait()释放锁
● sleep()方法指定一段时间睡眠,线程自动苏醒
wait()方法被调用后可以通过notify() notifyAll()方法进行调用
● sleep常用于线程暂停---wait常用于线程间交互
● sleep()不释放锁,wait()释放锁
● sleep()方法指定一段时间睡眠,线程自动苏醒
wait()方法被调用后可以通过notify() notifyAll()方法进行调用
线程中断
Interrupter
主要设置线程标志位,可以使用Interrupter优雅停止线程执行。Interrupter 打断一个线程
并发特性
三大特性
原子性
一个或多个操作要么全部执行成功要么全部执行失败
有序性
程序执行的顺序按照代码的先后顺序执行
可见性
一个线程对共享变量的修改,另外一个线程能够立刻看到
sync和volatile
synchronized: 具有原子性和可见性
volatile: 具有可见性
sync和volatile都不能保证指令的重排
缓存一致性协议
特性
从缓存读取内容时按照按照缓存行进行读取,多个线程对于修改同一处缓存行内容,
通过缓存一致性协议进行同步
通过缓存一致性协议进行同步
MESI
MESI是缓存一致性实现的一种,当一个线程修改了一个变量之后,
会将这个变量写入缓存,同时将其他线程使用的该变量置为无效
会将这个变量写入缓存,同时将其他线程使用的该变量置为无效
0 条评论
下一页