java高并发实战(一)——为什么需要并发 - Go语言中文社区

java高并发实战(一)——为什么需要并发


由于之前看的容易忘记,因此特记录下来,以便学习总结与更好理解,该系列博文也是第一次记录,所有有好多不完善之处请见谅与留言指出,如果有幸大家看到该博文,希望报以参考目的看浏览,如有错误之处,谢谢大家指出与留言。

一、为什么需要把并行?

  1. 业务需求
  1. 性能

二、了解下高手之间的过招(本人望尘莫及呀)

linux之父炮轰并行开发,主张大容量缓存

他说:硬件的性能无法永远提升,当前的趋势实际上趋于降低功耗。那么推广并行技术这个灵丹妙药又有什么好处呢?我们已经知道适当的乱序CPU是必要的,因为人们需要合理的性能,并且乱序执行已被证明比顺序执行效率更高。同时对锁主张原子引用计数。

没有人会回到过去,那些复杂的乱序运行内核不会消失。扩展不可能无休止的进行,人们需求更多的移动性,那些叫嚣扩展到上千核心的论调纯属扯淡,无需理会。对于终端用户来说,4核就差不多了,而在这个领域,如果不增加太多的能耗,你也无法塞入更多的内核。同时,也不会有智障去阉割内核,降低其大小和性能只为了多塞几个。通常情况下,阉割内核只是为了降低功耗,因此这里也不会有那么多阉割的内核让你使用。

他认为:对于并行来说,唯一的用武之地就是图形计算和服务器端,而并行计算在这些领域确实也得到了大量的应用。但是没有任何疑问,并行在其他领域毫无用武之地。

具体讨论观点请看

https://blog.csdn.net/cxzhq2002/article/details/42614045

http://blog.sina.com.cn/s/blog_16eb155530102xx8r.html

三、这里再说为什么需要并行

1.摩尔定律的失效

什么是摩尔定律:1、集成电路芯片上所集成的电路的数目,每隔18个月就翻一番。

                           2、微处理器的性能每隔18个月提高一倍,而价格下降一倍。

                           3、用一个美元所能买到的电脑性能,每隔18个月翻两番。

网上也说摩尔定律不会失效,但就之前2004年Inter对4GHz计划的取消,以及现在虽然有4GHz的芯片但频率极限已逼近,而且近10年停留在4GHz.因此我觉得是暂时性的失效

2.顶级计算机科学家唐纳德.尔文.克努斯

说:在他看来,这种现象(并发)或多或少是由于硬件设计者,已经无计可施了导致的,他们讲摩尔定律失效的责任推脱给软件开发者

3.并行计算还出于业务模型的需要

  • 并不是为了提高系统性能,而是确实在业务上需要多个执行单元
  • 比如HTTP服务器,为每一个socket连接新建一个处理线程
  • 让不通线程承担不同的业务工作
  • 简化任务调度

四、下面用图形简单介绍几个概念(网上资料很多,这里就概要下,不过这些概念都好理解)

1.同步(synchronous)和异步(asynchronous)

(1)同步交互:指发送一个请求,需要等待返回,然后才能够发送下一个请求,有个等待过程;

(2)异步交互:指发送一个请求,不需要等待返回,随时可以再发送下一个请求,即不需要等待。

 区别:一个需要等待,一个不需要等待,在部分情况下,我们的项目开发中都会优先选择不需要等待的异步交互方式。

可以理解为,同步在同一个执行时间上完成一个时间戳之后,才可以执行下一个时间戳。异步则可以另起一个线程去完成下一个时间戳任务,就是不会占用上一个执行时间。


2.并发(Concurrency)和并行(Parallelism)

我看到有说,他俩其实可以视为同一个概念,对于开发人员来说,可以不必区分太过区别,他们在外在表象都是一样的,但有些场合还是要区分下,但这里简单的做下区别,详细可查阅资料。

并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生。
并行是在不同实体上的多个事件,并发是在同一实体上的多个事件。

并发是一次处理很多事情,并行是同时做很多事情。

总之:并行是两个线程(或进程)同时执行,并发指一会做这件事情,一会做这件事情,一会做那件之情,他们有个调度的过程。

所以并发编程的目标是充分的利用处理器的每一个核,以达到最高的处理性能。并行只有在多核下才会有。


3.临界区

保证在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。 

4.阻塞(Blocking)和非阻塞(Non-Blocking)

并发级别

  • 阻塞

         当一个线程进入临界区,其他线程必须等待

  • 无障碍(非阻塞)

        无障碍是一种最弱的非阻塞调度

        自由出入临界区

        无竞争时,有限步内完成操作

        有竞争时,回滚数据

  • 无锁(非阻塞)

        是无障碍的

        保证有一个线程可以胜出

        while(!atomicVar.compareAndSet(localVar,localVar+1)){

            localVar = atomicVar.get();

        }

  • 无等待(非阻塞)

        无锁的

        要求所有的线程都必须在有限步内完成

        无饥饿的

5.死锁(Deadlock)、饥饿(Starvation)和活锁(LiveLock)

有两个人到饭店吃饭,但是只有两根筷子,他们两个人 一人一根。

死锁场景:两个人互相等待对方拿的一根筷子,各自都不做出让步,永远互相等待下去就发生死锁。

饥饿场景:两个人等待饭店再去拿一双筷子,结果饭店拿的比较慢,他俩等到饿死了,筷子还没有拿来,此时就发生了饥饿。
活锁场景:两个人一直在交换各自持有的筷子,但是无论如何交换,每个人还是各自持有一根筷子,永远也吃不了,此时属于活锁。
活锁:指的是任务或者执行者没有被阻塞,由于某些条件没有满足,导致一直重复尝试,失败,尝试,失败。
死锁:指的是两个或者两个以上的进程相互竞争系统资源,导致进程永久阻塞。
饥饿:指的是等待时间已经影响到进程运行,此时成为饥饿现象。如果等待时间过长,导致进程使命已经没有意义时,称之为“饿死”。

五、有关并行两个定律

阿姆达尔定律

定义:定义了串行系统并行化后的加速度比的计算公式和理论上限

加速比定义:加速比=优化前系统消耗时/优化后系统消耗时



古斯塔夫森

定义:说明处理器个数,串行比例和加速比之间的关系


由上面两个定律可总结出:优化性能总与n和f有关,虽然阿姆达尔定律增加cpu数量与性能成反比,古斯塔夫森却成正比,两个反例,但他们公式可得,同时控制串行比例与cpu个数(也就行并行)才可能达到性能最优化。

前言介绍目前到此结束,后续开始正式进入学习记录多线程部分。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/gududedabai/article/details/80813592
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-04-11 09:47:58
  • 阅读 ( 1132 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢