• 常江舟
    2019-02-26
    从性能角度讲,我们为了提高执行一定计算机任务的效率,所以IO等待的时候不能让cpu闲着,所以我们把任务拆分交替执行,有了分时操作系统,出现了并发,后来cpu多核了又有了并行计算。这里也就是作者说的[分工]。分工以后我们为了进一步提升效率和更加灵活地达到目的,所以我们要对任务进行组织编排,也就是对线程组织编排。于是线程之间需要通信,于是操作系统提供了一些让进程,线程之间通信的方式。也就是作者说的[同步]。但是事物总不是完美的。并发和通信带来了较高的编程复杂度,同时也出现了多线程并发操作共享资源的问题。于是天下大势,分久必合,我们又要将对共享资源的访问串行化。所以我们根据现实世界的做法设计了了锁,信号量等等来补充这套体系。也就是作者所说的[互斥]!

    综上,这一切均为提高性能的手段和对其所产生问题的解决方案。
    展开

    作者回复: 正解

    
     222
  • Jerry银银
    2019-03-06
    这篇文章看了四五篇,写得真好,收获也很多。
          文中提到了两点真是发人深省:
          1. 方法论层面:「跳出来,看全景」 和 「钻进去,看本质」,这两条方法论,我想是适合很多领域的学习的。
          2. 并发领域的「全景图」。
          对于「全景图」,我之前也有一直在构建,可是因为知识储备不够,确实很难构建出来。稍微了解过并发领域知识的人都知道,里面的知识点、概念多而散:线程安全、锁、同步、异步、阻塞、非阻塞、死锁、队列(为什么并发要跟队列扯上关系)、闭锁、信号量、活锁等等。如果单个去学这些知识点,单个去练习,如果没有「主线」,后期很容易忘。我思考再思考,也总结了一下学习并发的主线:
          首先,得理解并发的重要性,为什么需要并发?对于这个问题,只需要放在潜意识里面,只需要两个字:性能!其它的细节,再去慢慢拓展。
          然后,既然并发很重要,而并发处理的是任务,接下就是:对任务的抽象、拆解、分工执行。而线程模型,只是其中的一种模型,还有多进程、协程。Java使用的是多线程模型,对应到具体的代码就是:Thread, Runnable, Task,执行任务有:Exectors。 引出了线程,有势必存在着线程安全性的问题,因为多线程访问,数据存在着不一致的问题。
          再然后,大的任务被拆解多个小的子任务,小的子任务被各自执行,不难想象,子任务之间肯定存在着依赖关系,所以需要协调,那如何协调呢?也不难想到,锁是非常直接的方式(Monitor原理),但是只用锁,协调的费力度太高,在并发的世界里面,又有了一些其它的更抽象的工具:闭锁、屏障、队列以及其它的一些并发容器等;好了,协调的工作不难处理了。可是协调也会有出错的时候,这就有了死锁、活锁等问题,大师围绕着这个问题继续优化协调工具,尽量让使用者不容易出现这些活跃性问题;
          到此,「并发」的历史还在演化:如果一遇到并发问题,就直接上锁,倒也没有什么大问题,可是追求性能是人类的天性。计算机大师就在思考,能不不加锁也能实现并发,还不容易出错,于是就有了:CAS、copy-on-write等技术思想,这就是实现了「无锁」并发;
          可是,事情到此还没有完。如果以上这些个东西,都需要每个程序员自己去弄,然后自己保证正确性,那程序员真累死了,哪还有时间、精力创造这么多美好的应用!于是,计算机大师又开始思考,能不能抽象出统一「模型」,可能这就有了类似于「Java内存模型」这样的东西。
    ------------
    借用宝令老师的语言,以上「是我对并发问题的个人总结,不一定正确,但是可以帮助我快速建立解决并发问题的思路,梳理并发编程的知识,加深认识。我将其分享给你,希望对你也有用」。
    展开

    作者回复: 我觉得你比我总结的好👍

     2
     133
  • Minecraft
    2019-02-26
    并发编程学习 第一天 明天去面试 祝我好运
     1
     78
  • Jerry银银
    2019-03-06
    之前看薛兆丰的《经济学通识》,他总结到,人类面临着四大基本约束:东西不够,生命有限,互相依赖,需要协调。当我看到这句话的时候,我猛然间意识到:计算机也同样面临着这四大基本约束。

    在计算中,CPU、内存、IO、硬盘、带宽等,这些资源也都有不够的时候,而每个线程的也有着自己的生命周期,并且它们之间又是相互依赖的,也同样需要协调。

    有了上面的这种想法,我觉得我学习计算机的知识有了章法可循。
    展开

    作者回复: 好厉害

     3
     72
  • crazypokerk
    2019-02-26
    感觉确实如老师所说的,知识不成体系,就像是奶酪,看着是一块,实则满眼孔洞,加油!

    作者回复: 这个比喻我是服了

    
     35
  • 墙角
    2019-03-06
    正如老师所说,并发编程涉及的知识面比较广,无奈大学阶段没有学好,老师帮忙推荐下和并发编程相关的书籍。只有有了一定的知识铺垫,才能更好的理解并发编程。感谢!

    作者回复: 《Java并发编程实战》作者阵容可谓大师云集,也包括Doug Lea
    《Java并发编程的艺术》讲解并发包内部实现原理,能读明白,内功大增
    《图解Java多线程设计模式》并发编程设计模式方面的经典书籍
    《操作系统:精髓与设计原理》经典操作系统教材
    http://ifeve.com 国内专业并发编程网站
    http://www.cs.umd.edu/~pugh/java/memoryModel/ 很多并发编程的早期资料都在这里

    
     30
  • 凌
    2019-02-26
    令哥,你就坐我对面,让我如何评论啊!呵呵

    作者回复: 使劲夸就行了,我不介意

    
     29
  • Healtheon
    2019-02-26
    想给老师提一个建议,就是在开篇用一个问题来引出本篇所要讲述的内容,然后在结尾时的总结之前回答开篇的问题。最后,在总结之后再设计并提出一个问题,让大家来讨论和回答。每一课之后的激烈讨论将是最有意思的,望老师考虑一下,谢谢!

    作者回复: 你的建议非常好,我努力向这个方向前进

    
     23
  • 我会得到
    2019-02-26
    全局思维加单点突破,这种方式屡试不爽。希望令哥沉住气不着急,好好打磨,慢慢更新,搞出精品,打造业界标杆😁

    作者回复: 借你吉言

    
     21
  • minggushen
    2019-02-26
    老师想请教您一个问题,目前公司需要进行分表操作,单表2亿数据,每年的增量也是两亿。有没有什么理论基础支持我分片的片数,以及是否需要分库以及其他注意事项。如果没有的话,老师按照您的经验,应该分成多少个片呢?目前是用的哈希对128取模进行的,分成128个表,是否合适呢。

    作者回复: 建议先做个冷热分离吧,如果不能做,建议分库,分片规则很重要,要结合业务,具体问题具体分析。回头我再出个分布式计算的专栏......

     1
     12
  • 梅云霞
    2019-02-26
    总结

    当初我学习 Java 并发编程的时候,试图上来就看 Java SDK 的并发包,但是很快就放弃了。原因是我觉得东西太多,眼花缭乱的,虽然借助网络上的技术文章,感觉都看懂了,但是很快就又忘了。实际应用的时候大脑也一片空白,根本不知道从哪里下手,有时候好不容易解决了个问题,也不知道这个方案是不是合适的。
    说出了我的处境!如何记住Java SDK 的并发包就像记住ABC呢

    作者回复: 买个专栏啊

    
     8
  • 王二宝
    2019-02-26
    我和老师的观念是一样的,如果碰到自己一直搞不定的问题时,我的应对方法也是:从两个方面突破。一个是“跳出来,看全景”,另一个是“钻进去,看本质”。

    作者回复: 同感

    
     8
  • 冉
    2019-03-01
    个人一点建议因大家基础功底不一且并发知识面广,若专栏篇幅受限的话,还望讲的过程中给出一些相关链接知识,方便理解,望采纳!

    作者回复: 多谢建议,必须采纳!

    
     7
  • Joker
    2019-02-28
    这是我在极客学院购买的第一份产品,也是因为纯洁的微笑才买的这份产品,希望自己能坚持下去,在并发编程这方面有点突破

    编辑回复: 极客时间,哥哥

     1
     6
  • 邋遢的流浪剑客
    2019-02-26
    过年的时候看了一遍java并发编程的艺术,感觉有点晕,正好跟着老师的课在深入理解一下

    作者回复: 那本书属于高段位的,适合学完这个专栏后再看

    
     6
  • 发条橙子 。
    2019-02-26
    总结 :

    并发编程需要构造出一个全景图 。 只要分为三大点 : 分工、协作、互斥。

    先将一个大的逻辑按不同的工作去分配给不同的线程 , 这些线程可以同时进行 ,也可以一个线程结束后再进行下一个进程,这时就需要线程间的协作 , 最后如果是多个线程同时进行并且会访问同一个共享资源时就需要对这个资源加锁以便造成资源的不一致 ,这就是互斥

    当全景图有了就需要深入到各个点, java sdk 的并发包中提供了很多工具帮我们处理上面三大点, 比如分工的fork/join 、协作的 future 、 互斥的各种锁以及无锁原子类等 。

    这只是表面 , 我们更要深入其中了解其背后的理论,比如很多 sdk并发包中的工具都是基于管程的思想 。 了解了这个思想才能举一反三 ,站在更高的视野去理解并发的本质

    另外,希望老师也可以着重讲一些管程这类的原理概念,我也是第一次听到这个词甚是感兴趣 , 并且老师说道并发的处理大多涉及操作系统相关的知识,也希望老师能推荐一些书籍或者文章资料便于我们更深入的理解学习
    展开

    作者回复: 专栏有专门一期讲管程,每一期都会有相关推荐

    
     4
  • 拯救地球好累
    2019-07-16
    再谈如何学习并发编程?
        1. 高屋建瓴,整体架构->可以画出思维导图
        2. 深入本质,直抓核心->理论需要追根溯源,这里的源追到哪儿,对并发编程而言,我觉得到数据结构与算法、操作系统这一层面就足够了

    谈谈自己对分工、同步、互斥的理解?
    分工。分工其实有两个阶段,一是如何将一个大任务划分成多个小任务,二是如何将多个小任务交给多个线程去协作完成。前者老师称为任务分解,是我们在业务层面需要考虑的问题,有些问题是易于拆分的,如数组求和等,而有些问题的拆分却很难,是否利于拆分非常依赖于问题本身的复杂性和业务模型的设计好坏。后者则是一些并发包里为我们提供的一些分工方法和设计模式中为我们提供的指导法则。
    从操作系统的线程模型看分工:以Linux为例,其将线程分为用户级线程、轻量级进程、内核级线程三种,用户级线程处理用户态下的基本任务,而当中断等行为发生时,需要切换到内核态,由内核级线程执行中断服务程序。
    分工的实例:Executor,Frok/Join,Feture,各种并发设计模式等
    同步。同步是指线程间的协作。线程可以自己独立完成一些子任务,但在完成子任务的过程中或者完成后需要与其他线程交互协作,比如在线程完成一个子任务后需要返回结果给主线程、在子任务完成过程中可能与其他线程有依赖关系,需要等待其他线程某个信号的通知等。
    同步的实例:Semaphore,Monitor,CountDownLatch等
    互斥。互斥是并发程序对共享变量的保护措施,已达到线程安全的目的。导致共享变量不确定性的核心三大问题是可见性、有序性、原子性问题,而互斥则是解决这些问题的一种较强硬的手段---同一时刻,只有一个线程访问共享变量。
    互斥的实例:互斥锁和无锁等

    启发:
        1. 老师的这种既抓全局又抓原理核心的方式十分有收获,并且尝试自己归纳总结整体概念,《程序员的思维修炼》中曾谈到,我们的学习过程需要右脑思维和左脑思维的结合,右脑看森林,左脑看树木,这也是一种系统化的学习方式,希望在之后学习每一项新技术时都能做到这两点。
        2. 同学们对三个概念的理解从追根溯源地从CPU、内存、硬盘等角度思考为什么,很有启发
    展开

    作者回复: 👍👍总结的真好

    
     3
  • 木易走刀口
    2019-02-26
    好东西值得认真学习

    作者回复: 感谢杨总支持!

    
     3
  • balance
    2019-09-20
    并发编程全景图总结:出发点是为了提高【性能】,为了提高性能就得【分工】,分工做事就需要协做,协做即【同步】,在分工协做的同时,存在同时对共享资源的占用、操作的问题,那就带来了共享资源【安全】的问题,解决安全问题的方法就【互斥】。性能是要解决的问题,安全是引出的问题。为什么同时对共享资源的操作会有安全性问题,主要是因为【可见性】、【原子性】、【有序性】问题导致。
    
     2
  • 遠い道の先で
    2019-03-13
    1、跳出来看全景,钻进去看本质。
    -在进入一个新领域学习时,建立一张学习线路的全景图,由点成线由线成面,贯穿整个学习过程。
    -在学到某个具体问题时,钻进去看本质,了解技术背后的理论模型,了解当初这个理论产生的环境时什么,主要解决什么问题。
    2、一些重要的知识前任一定有所研究并有相应的结果,可以先查阅目前最可靠的解决方案,提高自己的基线。
    3、分工:将一个大的任务(项目)拆分成若干个小任务,并安排适合的成员去执行。
    4、同步:每个小任务间可能存在相互依赖,同步需要做的是在前置任务完成后,通知后置任务启动。
    5、互斥:互斥主要解决正确性问题。互斥要求同一时间,只允许一个线程访问共享变量。
    6、管程monitor是解决并非问题的万?能?钥匙。(这个完全不理解)
    7、一项优秀的理论往往在多个语言中都有体现,学习过程中应注重理论的学习。
    —————
    以上是听课过程中的笔记,下面说说自己的感悟:
            之前听过吴军老师的课程,讲到民间科学家为何难以作出成绩,是因为基线不高。老师在课中有讲到我们可以通过学习优秀前辈研究和成果去学习并发编程。非常同意两位老师的观点。
            跳出来看全景,钻进去看本质。这个观点很新颖我也非常认同,在日常的碎片化学习往往会让我们这学一点那些一点,感觉好像学了很多,但又感觉不知道学习什么。
            在学习前制定一张学习地图,就像一棵树先有树干再有树枝,会成长的枝繁叶茂的。
            平时遇到一个新的知识,我们可能一开始只知道怎么用,没有去探究它的本质,可能导致最终我们只会基础的使用而没有办法举一反三,下次遇到了还是新问题。
            这是第一次在极客时间购买课程,希望自己能跟上每一堂课,和大家一起成长。
    展开

    作者回复: 眼光不错哈哈

    
     2
我们在线,来聊聊吧