推荐手机网站建设,微信小程序cms系统,wordpress tag 收录,网站访问量统计怎么做Java 语言抽象和隐藏了各种操作系统线程差异性的接口#xff0c;这曾经是它区别于其他编程语言的一大优势#xff0c;但在某些场景下#xff0c;却已经出现了疲态#xff1b; 文章目录1. 内核线程的局限2. 协程的复苏3. Java 的解决方案1. 内核线程的局限
在微服务架构中这曾经是它区别于其他编程语言的一大优势但在某些场景下却已经出现了疲态 文章目录1. 内核线程的局限2. 协程的复苏3. Java 的解决方案1. 内核线程的局限
在微服务架构中要求每个服务提供者可以同时处理数量庞大的请求而不出现由某个服务被阻塞而整体等待
Java 目前的并发编程机制内核线程实现与此存在矛盾映射到操作系统上的线程的切换、调度成本高昂线程切换开销可能接近于计算本身的开销系统能容纳的线程数量有限
线程 A - 系统中断 - 线程 B从线程 A 切换到线程 B 之前操作系统首先需要把现场 A 的上下文数据妥善保管让后把寄存器、内存分页等恢复到线程 B 挂起时的状态这种保护与恢复现场的工作涉及一系列寄存器、缓存的来回拷贝不可能是一种轻量级的操作
2. 协程的复苏
栈纠绕Stack Twine有用户自己模拟的多线程、自己保护恢复现场的工作模式通过内存划分额外空间模拟调用栈让现场中的方法压栈、退栈遵守规则协程Coroutine被设计成协同式调度Cooperative Scheuling的用户线程 有栈协程Stackfull Coroutine会完整地做调用栈的保护、恢复工作无栈协程Stackless Coroutine有限状态机状态保存在闭包里比有栈协程更轻量功能也更有限await、async、yield 关键字应用
64 位 Linux 上 HotSpot 的线程栈容量默认是 1 MB内核数据结构额外消耗 16KB 内存而一个协程的栈通常在几百字节到几 KB可见 JVM 线程容量在 200 左右而协程容量可以到十万级
Java 调用栈与本地调用栈是在一起的在调用本地方法时切换协程可能影响整个线程一旦遭遇 synchronized 关键字挂起的仍是整个线程
3. Java 的解决方案
纤程Fiber一种有栈协程A light weight or user mode thread, scheduled by the Java virtual machine, not the operating system; Fibers are low footprint and have negilgible task-switching overhead. You can have millions of them!
Fiber 与目前线程模型保持相似的 API目标是与内核线程实现共存
5000 QPS400 线程 vs. 纤程线程 latency 在 10s ~ 20s而纤程 latency 在 200ms
纤程并发代码会被分为两个部分执行过程Continuation维护执行现场保护、恢复上线文状态和调度器Scheduler编排所有要执行的代码的顺序Loom 的默认调度器是 Fork/Join 池
可以使用 Quasar 协程库独立实现协程调度但由于其实现方式是通过字节码注入采用局部变量保存和恢复上下文存在较大性能问题且要求用户手动标准每一个需要使用协程的函数对即时编译器的干扰也较大 上一篇「JVM 高效并发」Java 线程
PS感谢每一位志同道合者的阅读欢迎关注、评论、赞 参考资料
[1]《深入理解 Java 虚拟机》