JUC并发编程
1|0JUC概念
- 进程和线程
一个进程包括多个线程
进程指的是一个正在运行的应用程序,进程是一个资源分配的最小单位
线程是程序中一个单元执行流,程序执行的最小单位
- 用户线程:基本我们编程的线程都是用户线程
主线程结束,用户线程还在,jvm存活
- 守护线程:如垃圾回收
用户线程设置成守护线程,主线程结束,没有其他用户线程,jvm结束
- 管程:
Monitor监视器,也就是所谓的锁,同步机制,保证同一时间,只有一个线程访问被保护数据或代码
-
wait/sleep
wait是object的方法,任何对象都能调用,会释放锁,调用他的前提是当前线程占有锁(代码在synchronized中)
sleep不会释放锁,他也不需要占用锁
-
线程状态
NEW 新建
RUNNABLE 准备就绪
BLOCKED 阻塞
WAITING 不见不散
TIMED_WAITING 过期不候
TERMINATED 终结
-
并发与并行
并发多个任务一个一个执行,多个线程访问同一个资源
如电商秒杀,抢票
并行是多个任务一起执行,多个线程一起执行最后汇总
2|0Future接口
异步任务,帮助主线程去做一些耗时的业务
三个特点:异步任务/有返回/多线程
输出 :
---come in call()
hello Callable
2|1Future 优缺点
输出:
---threadPool costTime: 572毫秒
---m1 costTime: 1140毫秒
get(3,TimeUnit.SECONDS); 设置超时时长,会抛出异常,可以自动离开,一定成可以避免阻塞,但是不优雅
缺点:
get()获取容易阻塞,需要等待get获取到,才会执行下面的程序
isDone()轮询耗费cpu
isDone()可以轮询查问是否执行完,拿到一次返回值
3|0CompletableFuture 常用方法
提供观察者模式,可以将执行任务完成后通知通知监听的一方
它实现了Future和CompletionStage接口
输出 :
ForkJoinPool.commonPool-worker-9
null
runAsync无返回值
输出 :
pool-1-thread-1
hello supplyAsync
supplyAsync 有返回值
CompletableFuture自定义线程池
输出:
ForkJoinPool.commonPool-worker-9---come in
main线程先去忙其他业务
--- 1秒后输出结果3
---计算完成,更新系统updateVa3
3|1CompletionFuture 优点
异步结束时,会自动回调某个对象的方法
主线程设置好回调后,不再关心异步任务的执行,异步任务之间可以顺序执行
异步任务出错时,会自动回调某个对象的方法
3|2CompletionFuture 函数
函数接口名称 | 方法名称 | 参数 | 返回值 |
---|---|---|---|
Runnable | run | 无参数 | 无返回值 |
Function | apply | 1个参数 | 有返回值 |
Consume | accept | 1个参数 | 无返回值 |
Supplier | get | 没有参数 | 有返回值 |
BiConsumer | accept | 2个参数 | 无返回值 |
3|3获取结果和触发计算
join和get对比
get 和 join 作用相同,但是get需要做抛出异常处理,jion不需要检查异常, 都要等待计算完成后的返回值
优雅的获取返回值,并防止阻塞:
getNow(T valueIfAbsent)
没有计算完成的情况下,给我一个替代结果
立刻获取结果不阻塞,计算完,返回计算完成后的结果,没计算完,返回设置的valueIfAbsent的值
complete(T value)
是否打断get方法立即返回括号值,打断会返回true ,将completeValue返回给join
输出:
no value
true completeValue
3|4对计算结果进行处理
thenApply
计算结果存在依赖关系,这是两个线程的串行化
由于存在依赖关系,当前步错,不能走下一步,会在当前步停止
输出
main-----主线程先忙其他业务
111
java.lang.ArithmeticException: / by zero
Handle
有异常也可以往下一步走,根据带的异常参数可以进一步处理
输出 :
main-----主线程先忙其他业务
111
222
java.lang.NullPointerException
3|5对计算结果进行消费
接受任务的处理结果,并消费处理,无返回结果
thenAccept
输出:
2
thenRun、 thenAccept、thenApply 区别
thenRun 任务A执行完执行B,B不需要传入值,也无返回值
thenAccept 任务A执行完执行B,B不需要传入值,有返回值
thenApply 任务A执行完执行B,B需要传入值,有返回值
输出:
null
resultA null
resultAresultB
thenRun和thenRunAsync区别
-
没有传入自定义线程池,默认使用线程池ForkJoinPool
-
传入一个自定义的线程池
如果你执行第一个任务的时候,传入了一个自定义线程池;
调用thenRun方法执行第二个任务时,则第一个任务和第二个任务是共用一个线程池
调用thenRunAsync执行第二个任务时,则第一个任务使用你传入的线程池,第二任务使用ForkJoinPool
-
备注
有可能处理的太快,系统优化切换原则,直接使用main线程处理
其他的thenAccept和 thenAcceptAsync,thenApply和thenApplyAsync等,也是同理
输出:
1号任务 pool-1-thread-1
2号任务 main
3号任务 ForkJoinPool.commonPool-worker-9
4号任务 ForkJoinPool.commonPool-worker-9
null
3|6对计算速度进行选用
applyToEither
谁快用谁
输出:
playA come in
playB come in
main playA is winer
对计算结果进行合并
thenCombine
输出:
playA come in
playB come in
30
__EOF__
作 者:走马观花
出 处:https://www.cnblogs.com/cool-fun/p/16379420.html
关于博主:编程路上的小学生,热爱技术,喜欢专研。评论和私信会在第一时间回复。或者直接私信我。
版权声明:署名 - 非商业性使用 - 禁止演绎,协议普通文本 | 协议法律文本。
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix