穿越线程的迷宫
-
底层知识,从根上开始 - 计算机的发展史
-
不懂硬件,就不懂软件 - CPU的电路原理
-
没有压迫,就没有性能 - 谈谈进程与线程
-
有多线程,就会有同步(1) - 缓存的一致性协议
-
有多线程,就会有同步(2) - 编译器屏障与指令屏障
-
有多线程,就会有同步(3)关中断、总线锁、缓存锁
-
加餐 在硬件的基础之上 - 操作系统级别的并发控制
-
超脱于语言之外,扎根于语言之内 - 底层同步与语言的关系
-
JAVA多线程起步
-
JVM如何启动线程(聊聊Hotspot线程管理)
-
解析可见性
-
解析有序性
-
解析原子性 - 深度解析synchronized
-
解析JUC - AQS源码
-
解析线程池
-
解析协程/纤程
-
JAVA多线程大课
-
JMH线程性能
-
Disruptor高性能框架
计算机的历史
算盘和机械计算机
有很多民族自豪感爆棚的兄弟会把算盘当成计算机的起源,还有爆破天的兄弟会把阴阳当成二进制0和1的起源,我觉得这件事儿就有点儿不靠谱了
如果非要追究计算机的鼻祖,那就得讲讲17世纪前欧洲的故事,最早的计算机其实是计算器,就是算数用的,在欧洲工业工业革命的时候,大量的工业模具需要计算,欧洲又没有中国传统的计算器 - 算盘,就催生了很多科学家发明自己的计算器(对,就是计算器,就是以前菜市场还在使用的那种,还不能称之为现在的计算机),这其中有个NB的人物,这个人叫布莱士帕斯卡,我们的压强单位(帕,千帕,百帕,兆帕)等等,就是以这哥们儿的名字命名,还有,计算机语言里面有一种叫做Pascal,就是为了纪念他。
就是这么个NB的人物,发明了最早的机械计算器,长这样儿:
经过后人的逐步改进,机械计算机的最后发展堪称精美,有长这样儿的:
还有长这样儿的:
还有更NB的:
机械计算机改进者中有个人值得一提,他就是德国百科全书式的天才,17世纪的亚里士多德 -- 莱布尼茨!
莱伯尼兹这个人又是个大牛,他既懂物理又懂数学(物理数学不分家),著名的微积分基本定理,牛顿莱布尼茨公式,就是莱布尼茨发明的,当然这里面是牛顿跟莱布尼茨或者说英国跟欧洲大陆的恩怨情仇。简单说,莱布尼茨发表论文创立微积分公式,牛顿当时是英国皇家学会的老大,话语权影响力比较大。牛顿说莱布尼茨发表的公式是参考了牛顿三年前的笔记,莱布尼茨嗓门不够响,争不过牛顿,所以没有办法,后人就把这个公式称为牛顿莱布尼茨公式。
一个人想在社会取得回报或者想发挥巨大作用,就必须要明白这个社会的运行机制,通过这件事儿,大家应该明白话语权的(传媒、笔杆子)重要性,如果还不能理解,参考美国把上个世纪的美国病毒命名为西班牙病毒这件事儿,当然最近又想把新冠病毒扣在我们脑袋上,就是因为他把控了话语权。衍生出来你应该明白的是,历史是个任人打扮的小姑娘,你看到的,你听到的,都是别人想让你看到和听到的,所以你要进行深度的思考,他是谁?为什么这么说?他说的是真的吗?对我有没有什么企图?多问自己几个为什么,你会慢慢从白痴成为智者。
扯远了,还说回来莱布尼茨,他除了改进机械计算机以外,还有一个重要的发明,那就是大名鼎鼎的二进制!(这里终于跟现代IT技术关联起来了)据说二进制的发明是参考中国古代的阴阳太极图而创作出来的,对此,我觉得倒是真的有可能。因为莱布尼茨有一本著名的著作,叫做《论中国人的自然哲学》,说明这个人对中国是有研究的。而且,他发明了二进制以后,还通知了当时的康熙大帝,因为他认为康熙大帝是个数学迷(对此我深表怀疑)。
当然,机械计算机又大又笨重,早就被现代的电子计算机所取代,不过说句题外话,机械计算机也有电子计算机所不具备的优点,就是结实耐用,几百年都不坏,而且,还不用电 ,谁要是大学食堂里面打饭收费做计算的时候来这么一台,那绝对是学妹眼中最酷的仔!
顺便也来一张现代电子计算机的鼻祖(当然,第一台电子计算机这件事儿也是见仁见智,美国嗓门大,所以现在资料大多认为1946诞生于美国宾夕法尼亚大学的“ENIAC”是世界上第一台电子计算机),它长这样儿:
这是个庞然大物,它大概占地一个别墅,跟一辆前苏联虎式坦克一样重,每个小时耗电150度,但是,每秒钟的计算量仅区区的5000次,要知道现在手机上的芯片的计算速度可以达到每秒10 0000 0000 0000次。不过就是这样一台还比上菜市场计算器的东西,开启了20世纪最NB的数字化革命!从此之后,计算机行业飞速发展,造就了现在所谓的信息化大革命。
严格讲,这台机器应该称作电子管计算机,因为,这里面用的零件全部都是电子管,电子管如果开关的速度太快,很容易就会坏掉,据说这台机器每天都会有电子管冒烟儿,工程师在寻找和修复每一个电子管中疲于奔命,想象一天24小时,计算时间仅有半小时,剩下的23个半小时都是在寻找和修复坏掉的点,这是多么让人抓狂的一件事。如果你不能理解这件事儿,想象一下一个灯泡每秒不停的开关5000次,它会不会坏掉。而且,电子管还有很严重的发热问题,需要把风扇进行紧密的排布,这也是一个工艺难题。
不过,幸运的是,在这台又笨重毛病又多的计算机问世的第二年,也就是1947年,美国贝尔实验室研究发明了晶体管,和电子管相比,晶体管体积又小,耗电还低,最重要每秒开关几十万上亿次都不带坏的,从这一刻开始,计算机革命才真正的进入了突飞猛进的时代。
这堂课,我们要讲的就是计算机的原理。
CPU的原理
为什么讲线程要讲CPU?因为线程和CPU有一对一的对应关系!(超线程除外)
当然,现代的计算机的核心,也就是芯片,是由10 0000 0000 个零件构成,我没有办法带你走遍这里面的每一个细节,不过,作为高级语言的程序员,我会带你走到足够深的深度,让你能够深入理解你写的每一行代码到底在计算机内部是怎么转换成电信号,从而被精密执行的。这一点很重要,因为这会给你带来“通透感”(原谅我找不到更好的形容词,现在很多程序员是没有经过科班训练的,是根据业务进行速成的,对这样的小伙伴儿来说,你写的代码虽然可以工作,但是它对你是一个黑盒子,你看不到代码背后的一切,从而也就无法进行更深入的理解和更准确的调优,总之,我个人非常喜欢这种通透感,我不喜欢一个技术对我来说是黑盒,是秘密,希望你也能理解和享受这种通透感)
好吧,让我们揭开代码背后的神秘世界。
还要从一个故事谈起。
我小时候最喜欢的女同学叫小芳,长的好看又善良,我们俩情投意合,每天放学后都约会共同进步,童年的时候山青水白,鸟语花香,环境特别好,我们的年纪都很小,我爱谈天她爱笑,有一回并肩坐在桃树下,风在林梢鸟在叫,不知怎么就睡着了,梦里花落知多少...
不要打断我,让我陷在美好的回忆中不可自拔一会儿。
只不过后来大人发现了我们的联系,用他们自带的污秽的思想,认为我们的关系是污秽的,是不纯洁的,我们当时还没有罗密欧与朱丽叶,梁山伯与祝英台这样的觉悟,不懂得以死相争,所以就被双方家长棒打鸳鸯,各自关了禁闭。
不过这个难不倒刚刚学了电学的我,我们就设立了这样入门级别的电路:
我还发明了灯泡语言:
-
亮亮 = 放
-
亮灭 = 学
-
灭亮 = 等
-
灭灭 = 我
当然你会发现如果只有两个信号的组合,就最多表示四个字,如果想沟通更顺畅,我只要增加信号的组合长度就可以了,比如三个信号,我就可以表示八个字
-
亮亮亮 = 放
-
亮亮灭 = 学
-
亮灭亮 = 等
-
亮灭灭 = 我
-
灭灭亮 = 一
-
灭灭灭 = 起
-
灭亮灭 = 电
-
灭亮亮 = 影
如果想交流的更加复杂,我可以增加更长的信号组合,比如我如果用16个长度的信号,就可以表示2^16个汉字,这个数字是65536,要知道,我们日常的汉字常用的话也就4000个左右,整个康熙字典的总字数也仅仅47000个,我用灯泡信号的长度仅需要16个信号长,就足矣涵盖中文的交流了。
思考题:如果仅需要覆盖日常交流(4000个汉字),我需要的信号组合的长度至少是多少?
灯泡语言有些复杂,我结合莱布尼茨的二进制,用1来代表灯泡亮(通电),用0来代表灯泡灭(断电),这样我和小芳就有了自己的通信语言,比如下面这句话,你猜我说了什么?
111 110 001 000 = (? )把答案写到括号里。
话说到这里,不知道大家有没有发现,我发明了一种汉字编码,就是把特定的汉字用0和1的组合表示出来,注意,汉字的编码并不是只有一种方式,完全有可能发生的是,在一种的编码方式中,111代表'我',而在另外一种编码方式中111代表'中',如果我们在解析一段编码的用错了编码格式,就会出现平时经常遇见的'乱码'问题。
思考题:A编码中,111 = 我 110 = 你,B编码中 111 = 沙 110 = 雕,那么下面这段话究竟代表什么呢?
110 111 110
再有了第一个电路的基础之上,我有设计了下面的电路:
这里就有了输入和输出的概念了
输入1 |
输入2 |
输出 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
可以用这样的符号表示:
也可以有这样的电路:
加法器
输入1 |
输入2 |
加和输出 |
进位输出 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
1 |
0 |
1 |