Java性能调优实战
刘超
金山软件西山居技术经理
立即订阅
7535 人已学习
课程目录
已完结 48 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 怎样才能做好性能调优?
免费
模块一 · 概述 (2讲)
01 | 如何制定性能调优标准?
02 | 如何制定性能调优策略?
模块二 · Java编程性能调优 (10讲)
03 | 字符串性能优化不容小觑,百M内存轻松存储几十G数据
04 | 慎重使用正则表达式
05 | ArrayList还是LinkedList?使用不当性能差千倍
加餐 | 推荐几款常用的性能测试工具
06 | Stream如何提高遍历集合效率?
07 | 深入浅出HashMap的设计与优化
08 | 网络通信优化之I/O模型:如何解决高并发下I/O瓶颈?
09 | 网络通信优化之序列化:避免使用Java序列化
10 | 网络通信优化之通信协议:如何优化RPC网络通信?
11 | 答疑课堂:深入了解NIO的优化实现原理
模块三 · 多线程性能调优 (10讲)
12 | 多线程之锁优化(上):深入了解Synchronized同步锁的优化方法
13 | 多线程之锁优化(中):深入了解Lock同步锁的优化方法
14 | 多线程之锁优化(下):使用乐观锁优化并行操作
15 | 多线程调优(上):哪些操作导致了上下文切换?
16 | 多线程调优(下):如何优化多线程上下文切换?
17 | 并发容器的使用:识别不同场景下最优容器
18 | 如何设置线程池大小?
19 | 如何用协程来优化多线程业务?
20 | 答疑课堂:模块三热点问题解答
加餐 | 什么是数据的强、弱一致性?
模块四 · JVM性能监测及调优 (6讲)
21 | 磨刀不误砍柴工:欲知JVM调优先了解JVM内存模型
22 | 深入JVM即时编译器JIT,优化Java编译
23 | 如何优化垃圾回收机制?
24 | 如何优化JVM内存分配?
25 | 内存持续上升,我该如何排查问题?
26 | 答疑课堂:模块四热点问题解答
模块五 · 设计模式调优 (6讲)
27 | 单例模式:如何创建单一对象优化系统性能?
28 | 原型模式与享元模式:提升系统性能的利器
29 | 如何使用设计模式优化并发编程?
30 | 生产者消费者模式:电商库存设计优化
31 | 装饰器模式:如何优化电商系统中复杂的商品价格策略?
32 | 答疑课堂:模块五思考题集锦
模块六 · 数据库性能调优 (8讲)
33 | MySQL调优之SQL语句:如何写出高性能SQL语句?
34 | MySQL调优之事务:高并发场景下的数据库事务调优
35 | MySQL调优之索引:索引的失效与优化
36 | 记一次线上SQL死锁事故:如何避免死锁?
37 | 什么时候需要分表分库?
38 | 电商系统表设计优化案例分析
39 | 数据库参数设置优化,失之毫厘差之千里
40 | 答疑课堂:MySQL中InnoDB的知识点串讲
模块七 · 实战演练场 (4讲)
41 | 如何设计更优的分布式锁?
42 | 电商系统的分布式事务调优
43 | 如何使用缓存优化系统性能?
44 | 记一次双十一抢购性能瓶颈调优
结束语 (1讲)
结束语 | 栉风沐雨,砥砺前行!
Java性能调优实战
登录|注册

19 | 如何用协程来优化多线程业务?

刘超 2019-07-02
你好,我是刘超。
近一两年,国内很多互联网公司开始使用或转型 Go 语言,其中一个很重要的原因就是 Go 语言优越的性能表现,而这个优势与 Go 实现的轻量级线程 Goroutines(协程 Coroutine)不无关系。那么 Go 协程的实现与 Java 线程的实现有什么区别呢?

线程实现模型

了解协程和线程的区别之前,我们不妨先来了解下底层实现线程几种方式,为后面的学习打个基础。
实现线程主要有三种方式:轻量级进程和内核线程一对一相互映射实现的 1:1 线程模型、用户线程和内核线程实现的 N:1 线程模型以及用户线程和轻量级进程混合实现的 N:M 线程模型。

1:1 线程模型

以上我提到的内核线程(Kernel-Level Thread, KLT)是由操作系统内核支持的线程,内核通过调度器对线程进行调度,并负责完成线程的切换。
我们知道在 Linux 操作系统编程中,往往都是通过 fork() 函数创建一个子进程来代表一个内核中的线程。一个进程调用 fork() 函数后,系统会先给新的进程分配资源,例如,存储数据和代码的空间。然后把原来进程的所有值都复制到新的进程中,只有少数值与原来进程的值(比如 PID)不同,这相当于复制了一个主进程。
采用 fork() 创建子进程的方式来实现并行运行,会产生大量冗余数据,即占用大量内存空间,又消耗大量 CPU 时间用来初始化内存空间以及复制数据。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Java性能调优实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(25)

  • 小橙橙
    老师,以后的JAVA版本是不是也会自带协程功能?

    作者回复: 是的,Java未来的三个主要项目之一Loom项目 引入了被称为 fibers 的新型轻量级用户线程,甲骨文公司 Loom 项目技术负责人 Ron Pressler 在 QCon 伦敦 2019 大会上指出:“利用 fibers,如果我们确保其轻量化程度高于内核提供的线程,那么问题就得到了解决。大家将能够尽可能多地使用这些用户模式下的轻量级线程,且基本不会出现任何阻塞问题”。

    具体的可以阅读以下openjdk官网链接:
    https://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html

    2019-07-05
    4
  • 欧星星
    老师有几个疑问
    1. 协程必须手动调用等待或阻塞才能被安排到等待队列去吗?还是说协程也可以跟线程一样会被随机丢到等待队列去每个协程也有个运行时间片?如果可以随机一般是如何实现的?
    2. 协程之间的争抢基于什么实现的?我想的话可以使用CAS来实现没有抢到的再次被丢到等待队列不知道对不对。
    3. 我看例子上邮箱里面没有数据时消费者协程没有类似线程的等待机制,这个要如何写呢?
    2019-07-02
    3
  • QQ怪
    老师讲协程讲的最深最易懂的一个,赞赞赞
    2019-07-02
    2
  • -W.LI-
    老师好!1:1,N:1,N:M的线程模型。总感觉上学的时候有讲可是又想不起来。谢谢老师的讲解。不过还是有些不明白的地方。
    Java是采用1:1的映射方式。一个Java线程就对应一个内核线程。用户态和内核态的切换和这个映射模型有关系么(用户态和内核态,和用户线程内核线程是否有关系)?
    从用户态切换为内核态的时候具体做了哪些操作?之前讲IO模型时老师讲了,用户空间和内核空间,多次数据拷贝。和用户线程内核线程有什么联系么?后面会讲么?
    2019-07-02
    1
  • 听雨
    老师,读了今天的内容,我理解的意思是:
    1.因为每个轻量级线程都有一个内核线程支持,而java中,每个用户线程对应一个轻量级线程,可以看作用户线程和支持轻量级线程的内核线程是一对一的,所以就说java线程模型是用户线程和内核线程一对一。
    2.那这里轻量级线程属于内核线程吗,我看文中说的是由内核线程clone而来的,那它算内核线程吗?
    请老师解答一下!

    作者回复: 1、对的
    2、属于用户线程,与内核线程一对一映射

    2019-07-02
    1
  • 慎独
    老师,协程在高并发系统中使用过吗?

    作者回复: 协程可以胜任高并发场景,不过目前没有在线上的Java项目使用过协程

    2019-12-04
  • neohope
    1. Java框架的话,Kilim有一段时间没有更新了,最近Quasar好像流行一些。
    2. JVM里,可以混用Kotlin;或者是混用Scala+akka。
    3. 未来版本的JDK也会逐步支持协程,但现在的实验版本好像只是在Linux下支持的比较好。
    4 .不过说实话,现在的netty框架,在一定意义上工作原理和协程也有一些相似之处。

    作者回复: netty在处理同步业务场景下,特别是业务处理比较耗时的场景下,并发处理能力有限。

    2019-11-22
  • 晓晨同学
    请问老师,上面说N:1这种线程模型是当某个用户线程使用内核线程阻塞的时候会使整个进程下的所有用户线程阻塞,那我想为什么不能像N:M线程模型一样当某个用户线程阻塞时就挂起来从而去调度其他的用户线程呢
    2019-11-13
  • Ericens
    老师,请教个关于协程与线程的疑问。比如,a协程调用socket. read(),此时数据没有准备好,则继续调度b协程。

    把协程换成线程,上面这个过程哪个更加轻量?协程还是线程?
    我理解这个过程涉及的过程如下,都一样。
    1.都有系统调用read(),从用户态切换到了内核态,
    2.都有上下文切换。(不同协程的寄存器,和不同线程的寄存器)
    3. 都要执行任务调度。协程调度或者线程调度。

    那协程到底轻量在哪?

    作者回复: 协程更轻量级,协程是线程的子集,所以不会存在线程间的上下文切换,而仅仅是通过调度器来完成调度的。

    2019-10-11
    1
  • godtrue
    课前思考及问题
    1:协程是啥?
    2:协程更轻量怎么体现,它轻量在哪里?
    3:为什么多协程没有高并发的问题?
    4:协程真这么优秀,为啥没有全面支持或使用?换言之实现协程需要什么代价?
    昨晚休息的太晚了,今天脑袋晕晕的,状态不佳感觉学完还是回答不好,课前的思考题。先跳过,回头再看一下。

    课后思考及问题
    1:协程与线程最大的不同就是,线程是通过共享内存来实现数据共享,而协程是使用了通信的方式来实现了数据共享,主要就是为了避免内存共享数据而带来的线程安全问题。
    这里的通信方式具体指什么?它比共享内存通信的方式还要快嘛?每个协程间都需要建立这种通信方式不耗资源不影响性能嘛?

    2:而 Go 语言是使用了 N:M 线程模型实现了自己的调度器,它在 N 个内核线程上多路复用(或调度)M 个协程,协程的上下文切换是在用户态由协程调度器完成的,因此不需要陷入内核,相比之下,这个代价就很小了。
    协程的执行不需要CPU?若需要,就会存在切入切出,协程的上下文切换怎么能在用户态全部完成,这个没有理解?

    作者回复: 1、这里说的通信方式是指协程间的通信方式,是通过数据共享来实现的,不存在线程安全问题;
    2、需要CPU,协程可以更充分的利用好CPU,不会来回切换资源。

    2019-09-10
    1
  • 帽子丨影
    文中提到协程有个队列,最终还是需要主线程来调度执行。那是不是有点类似线程池。主线程是Worker线程,每一个协程就是一个Task。只不过主线程执行到的某个Task阻塞时会去执行下一个Task。

    作者回复: 对的,这样理解很清晰

    2019-08-16
  • ~Wade
    有一个java库叫Quasar Fiber ,通过javaagent技术可以实现轻量级线程 
    官网:http://www.paralleluniverse.co/quasar/
    2019-07-24
  • 行者
    从前,操作系统调度线程运行;现在,有了协程,进程自己调度协程如何运行,避免不必要的上下文切换,且协程相比线程占用内存空间更少。
    协程主要来解决网络IO问题。

    作者回复: 对的,减少阻塞,充分利用CPU。

    2019-07-19
  • 宝玉
    有没有具体场景的实战优化呢?

    作者回复: 在socket通信中,可以使用协程优化IO读写这块。例如,可以尝试用协程写个非阻塞Socket通信,或用协程简单改造下Netty。具体的实现自己可以尝试,如果遇到问题欢迎沟通。

    2019-07-06
  • Liam
    消费者从mailbox拿数据为空时,或生产者往mailbox写数据没有可用空间时,不会阻塞吗?类似于队列

    作者回复: 会的,在mailbox为空时,消费者get会被阻塞;在mailbox满了,生产者put会阻塞。

    2019-07-03
  • cricket1981
    AKKA Framework算得上一个,另外还有Vert.X
    2019-07-02
  • 欧星星
    有个疑问,线程的切换是由系统来保证的,那协程之间的切换也能跟线程那样由调度器保证,还是说协程必须要手动调用或io

    作者回复: 由调度器保证

    2019-07-02
  • 风翱
    一核的CPU是否有使用协程的必要? 按目前cpu的调度是采用时间片的方式,一核的CPU也存在上下文切换。一核的CPU也可以应用到协程带来的好处。 不知道这个理解是否正确?

    作者回复: 对的

    2019-07-02
  • crazypokerk
    老师,不是建议不要使用String对象作为锁对象吗?为什么上面的代码private static String LOCK = "lock",要这么写呢?

    作者回复: 没有其他成员变量引用"lock",这里使用没有问题,具体场景具体分析。

    2019-07-02
  • Jxin
    loom项目也可以让javaer玩玩协程,不过仅限于玩玩。总归没有大项目验证,而且都非官方版本,而是以框架的形式引用。不建议在真实项目中去使用。另外erland的并发编程并不弱于go。就目前来看,感觉还是java比较适合写web项目。虽然go写并发编程很爽,但web开发组件不健全,很多东西得自己实现,而自己实现意味着成本和风险。能有现有,经过大项目和时间验证的组件终是比较让人舒心的。

    作者回复: 对的,一些技术框架还是需要经受大公司或者一些大型项目的验证,不过我们也可以先在一些小型项目中先行使用。

    2019-07-02
收起评论
25
返回
顶部