JAVA高并发——了解并行世界

        最近不知道怎么了,感觉什么东西都需要画画图,梳理梳理思路、写写,而且每每晚上坐到自己的位置上,打开本书,打开篇文章,打开思维导图,打开onenote,再打开音乐,然后就开始静静理解着,梳理着,画图着,编写着……感觉心情也能平静下来。netty源码还需要多花点时间理解理解,周末再进行;今天开始把Java高并发多线程的知识也回顾整理一吧。

       以前学习高并发多线程的过程,现在想想就是看知识点,怎么实现代码,很少去想为什么是这样,为什么会这样?而接下来,我希望能够通过思维导图,能够通过联想,能够通过关联,不断完善自己的知识网,使一些知识融入到自己的知识网中,达到牵一发动全身的效果。好,下边进入正题吧。

 

        一,高并发多线程的由来:

       摩尔定律 大家应该都听说过,大致意思是:当价格不变时,集成电路上可容纳的元器件的数目,约每隔18—24月便会增加一倍,性能也将提升一倍。但是摩尔定律并不是一种自然法则或者物理定律,随着硬件技术的发展,一些高科技技术越来越难突破,摩尔定律在CPU的计算性能上可能慢慢失效。(一个人干活,随着干活的技巧、经验越来越丰富,这个人干活的效率越来越高,但是当这个人已经达到效率没法再有质的提高的时,怎么办?善假于物业,找人一块帮着干)。人类的智慧是无穷无尽的,当单核CPU的性能无法提高时,那就双核、四核、多核……让多个cpu一起帮着处理需求,这样高并发多线程就来了。(以前是硬件研发人员不断的提高自己要求自己,现在也督促着软件开发人员不停的提高自己要求自己了)。

 

       二,高并发多线程的几个概念:

       1,同步(Synchronous)和异步(Asynchronous):方法调用一旦开始,调用者必须等到方法调用返回后,才能继续后续行为的属于同步;异步更像一个消息传递,一旦开始,方法就会立即返回,调用可以继续后续的行为。联想一下:TCP、UDP;打电话、发短信;RPC方法调用、MQ消息提供者消费者;单线程、多线程……

       2,并发(Concurrency)和并行(Parallelism):并行偏重两个或多个任务同时执行;并发偏重多个任务交替执行。都可以表示多个任务一起执行。单核CPU没法并行,只能并发,多个线程的不同任务,CPU交替执行(由于CPU执行效率特别高),看起来像”同时“执行,其实只是交替一起执行而已。

       3,临界区(Critical region):用来表示一种公共资源或者说是共享数据,可以被多个线程使用。例如:办公室的打印机,大家都可以使用,但是同一时间只能为一个员工服务,不能及打印员工A的又打印员工B的,那样应该就出问题了。我们临界区资源也是,一次被一个线程占用,其它线程只能排队,不能同时多个线程对其进行处理。这也就是我们经常说的共享资源在多线程的情况下需要加锁。

       4,阻塞(Blocking)和非阻塞(Non-Blocking):接着上边你说,如果临界区的资源被一个线程占用了 ,另一个线程只能等待,就会挂起也就是阻塞。

       5,死锁(Deadlock)、饥饿(Starvation)和活锁(Livelock):死锁:几个例子,做一件需要两个资源A、B,线程1拿到了A,线程2拿到了B,从而导致两个线程一直在等着彼此,像死循环一样,解不开;            饥饿:是指某一个或者多个线程因为种种原因无法获得所需的资源,导致一直无法执行,比如它的线程优先级可能太低,而高优先级的线程不断抢占它需要的资源;          活锁:是指线程1可以使用资源,但它很礼貌,让其他线程先使用资源,线程2也可以使用资源,但它很绅士,也让其他线程先使用资源。这样你让我,我让你,最后两个线程都无法使用资源。活锁不会被阻塞,而是不停检测一个永远不可能为真的条件。除去进程本身持有的资源外,活锁状态的进程会持续耗费宝贵的CPU时间。

 

       三,并发级别:

       阻塞(Blocking)——》无饥饿(Starvation-Free)——》无障碍(Obstruction-Free)——》无锁(Lock-Free)——》无等待(Wait-Free),并发级别依次变高。

 

       四,有关并行的两个重要定律:

       加速比定义:加速比 = 优化前系统耗时/优化后系统耗时。串行系统并行化后的加速比的计算公式和理论上限的公式定律:Amdahl定律 :当CPU处理器数量趋于无穷时,加速比与系统的串行化率成反比;例如如果系统中有50%的代码串行执行,那么系统的最大加速比为2;Gustafson定律 :如果串行化比例很小,并行化比例很大,那么加速比就是处理器的个数。  两者角度不同,一个从优化前执行时间、优化后执行时间,看cpu个数的影响,只有再有串行部分的情况下它是有上限的;二是从优化前执行时间、优化后执行总时间(并行的时间加起来),看cpu个数的影响,只要在串行部分足够小的情况下,是一直有优化空间的。一个是有上限,一个是我们可以不断提高的。

 

       五,JMM的关键技术点都是围绕着多线程的原子性、可见性和有序性来建立的。

       1,原子性(Atomicity):是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。

       2,可见性(Visibility):是指当一个线程修改了某一个共享变量的值,其他线程是否能够立即知道这个修改。

       3,有序性(Ordering):jvm执行命令是由指令重排会打错一些多线程指令的执行顺序(指令重排可以保证串行语句一致,但是没有义务保证多线程间的语义也一直。具体的回头在JVM的总结中会详细说到),这里重点看下Happen-Before规则:

       a,程序顺序原则:一个线程内保证语义的串行性;

       b,volatile规则:volatile变量的写,先发生于读,这保证了volatile变量的可见性;

       c,锁规则:解锁必然发生在随后的加锁前;

       d,传递性:A优先于B,B优先于C,那么A必然优先于C;

       e,线程启动规则:线程的start()方法优先于它的每一个动作;

       f,线程终止规则:线程的所有操作优先于线程的终结;

       g,线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断时间的发生;

       h,对象终结规则:对象的构造函数执行、结束先于finalize()方法。

 

      好,这篇重要扯了扯闲篇,了解了一下高并发多线程下的一些概念名词。希望结合实际联想,构建并不断完善自己的知识网。好,初入高并发多线程、接下来继续……

猜你喜欢

转载自blog.csdn.net/liujiahan629629/article/details/84039097