上一篇文章此次走进并发的世界,请不要错过 给你们带了并发编程的开胃菜,接下来咱们逐步上正餐,在吃正餐以前,我还要引用那首诗词: 「横当作岭侧成峰,远近高低各不一样」,远看看轮廓,近看看细节,不断切换思惟或视角来学习java
远看并发,并发编程能够抽象成三个核心问题: 分工、同步/协做、互斥面试
若是你已经工做了,那么你必定据说过或者正在应用敏捷开发模式来交付平常的工做任务,咱们就用你熟悉的流程来解释这三个核心问题编程
将当前 Sprint 的 Story 拆分红「合适」大小的 Task,而且安排给「合适」的 Team Member 去完成后端
这里面用了两个「合适」,将 Story 拆分红大小适中,可完成的 Task 是很是重要的。拆分的粒度太粗,致使这个任务完成难度变高,耗时长,不易与其余人配合;拆分的粒度太细,又致使任务太多,很差管理与追踪,浪费精力和资源。(合适的线程才能更好的完成整块工做,固然一个线程能够轻松搞定的就不必多线程);安排给合适的人员去完成一样重要,UX-UE 问题交给后端人员处理,很显然是有问题的 (主线程应该作的事交给子线程显然是解决不了问题的,每一个线程作正确的事才能发挥做用)安全
关于分工,常见的 Executor,生产者-消费者模式,Fork/Join 等,这都是分工思想的体现多线程
任务拆分完毕,我要等张三的任务,张三要等李四的任务,也就是说任务之间存在依赖关系,前面的任务执行完毕,后面的任务才能够执行,人高级在能够经过沟通反复确认,确保本身的任务能够开始执行。但面对程序,咱们须要了解程序的沟通方式,一个线程执行完任务,如何通知后续线程执行并发
全部的同步/协做关系咱们均可以用你最熟悉的 If-then-else 来表示:工具
if(前序任务完成){ execute(); }else{ wait(); }
上面的代码就是说:当某个条件不知足时,线程须要等待;当某个条件知足时,线程须要被唤醒执行,线程之间的协做多是主线程与子线程的协做,多是子线程与子线程的合做, Java SDK 中 CountDownLatch 和 CyclicBarrier 就是用来解决线程协做问题的性能
分工和同步强调的是性能,可是互斥是强调正确性,就是咱们经常提到的「线程安全」,当多个线程同时访问一个共享变量/成员变量时,就可能发生不肯定性,形成不肯定性主要是有可见性
、原子性
、有序性
这三大问题,而解决这些问题的核心就是互斥学习
互斥
同一时刻,只容许一个线程访问共享变量
来看下图,主干路就是共享变量,进入主干路一次只能有一辆车,这样你是否理解了呢?「天下大事,分久必合」
一样 Java SDK 也有不少互斥的解决方案,好比你立刻就能想到 synchronized 关键字,Lock,ThreadLocal 等就是互斥的解决方案
资本家疯狂榨取劳动工人的剩余价值,得到最大收益。当你面对 CPU,内存,IO 这些劳动工人时,你就是那个资本家,你要思考如何充分榨取
它们的价值
当一个工人能干的活,毫不让两我的来干(单线程能知足就不必为了多线程) 当多个工人干活时,就要让他们分工明确,合做顺畅,没矛盾
当任务很大时,因为 IO 干活慢,CPU 干活快,就不必让 CPU 死等当前的 IO,转而去执行其余指令,这就是榨取剩余价值
,如何最大限度的榨取其价值,这就涉及到后续的调优问题,好比多少线程合适等
分工是设计,同步和互斥是实现,没有好的设计也就没有好的实现,因此在分工阶段,强烈建议你们勾划草图,了解瓶颈所在,这样才会有更好的实现,后续章节的内容,我也会带领你们画草图,分析问题,逐步养成这个习惯
本章内容能够用下面的图来简单归纳,叶子结点的内容咱们会逐步点亮,现阶段不用过度关注(若是你上来就啃 JDK 源码,也许你会痛苦的迷失,并最终放弃你的进阶之路的)
理解三大核心问题,你要充分结合生活中的实际,程序中的并发问题,基本上都能在实际生活中找获得原型
下一篇文章的内容,咱们就要聊聊,引发线程安全的三个问题:「可见性,原子性,有序性」,这涉及到 JMM 的一点内容,能够提早了解一下的,这样咱们才能更好的碰撞
欢迎持续关注公众号:「日拱一兵」
- 前沿 Java 技术干货分享
- 高效工具汇总 | 回复「工具」
- 面试问题分析与解答
- 技术资料领取 | 回复「资料」
以读侦探小说思惟轻松趣味学习 Java 技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,请持续关注......