一、并发与并行
1.并发:并发就是指程序同时处理多个任务的能力。并发的实质是一个物理CPU(也可以多个物理CPU) 在若干道程序之间多路复用,并发性是对有限物理资源强制行使多用户共享以提高效率。 并发编程的根源在于对多任务情况下对访问资源的有效控制
2.并行:并行性指两个或两个以上事件或活动在同一时刻发生。在多道程序环境下,并行性使多个程序同一时刻可在不同CPU上同时执行
而并发则不一定并行,也亦是说并发事件之间不一定要同一时刻发生。
举个例子:
并发 :像骑车看风景 只能一边看一边骑车 在看和骑的时候快速切换(一个cpu的时候并发)
并行 :像坐缆车 看风景 可以同时进行互不影响(多个cup的时候同时处理多件事情)
二、程序,线程,进程,协程,go协程
程序:是静态的概念,windows下通常指exe文件。
进程:是动态的概念,是程序在运行状态,进程说明程 序在内存中的边界。
进程状态:进程的基本状态有5种。分别为初始态、就绪态、运行态、挂起态、终止态。其中初始态为进程准备阶段,常与就绪态结合来
线程:LWP(light weight process)轻量级进程,进程内的一个”基本任务”,每个线程都有自己 的功能,是CPU分配与调度的基本单位,CPU分配时间轮片的对象。产生原因:提高争夺到CPU的概率
协程:coroutine,也叫轻量级线程。 与传统的系统级线程和进程相比,携程最大的优势在于“轻量级”,可以轻松创建上万个而不会导致系统资源衰歇。而线程和进程通常很难超过1万个。一个线程中可以有任意多个协程,但某一时刻只能有一个协程在运行,多个协程分享该线程分配到的计算机资源。
产生原因:提高程序执行的效率。(利用闲暇时间执行其他任务)
go协程:叫goroutine。在进程中创建。它比线程更小,十几个goroutine可能体现在底层就是五六个线程,go语言内部帮你实现了这些goroutine之间的内存共享。执行goroutine只需要极少的栈内存(大概4~5kb),当然会根据相应的数据伸缩。也正因为如此,可同时运行成千上万个并发任务。goroutine比thread更易用,更高效,更轻便。一般情况下,一个普通计算机跑几十个线程就有点负载过大了,但是同样的机器却可以轻松的让成百上千个goroutine进行资源竞争
三、同步与异步
同步:同步方法调用一旦开始,调用者必须等到方法调用返回后,才能继续后续的行为。(核心:前面事情做不完,后面事情做不了)
异步:异步方法调用更像一个消息传递,一旦开始,方法调用就会立即返回,调用者就可以继续后续的操作。而,异步方法通常会在另外一个线程中,“真实”地执行着。整个过程,不会阻碍调用者的工作(前面事情不影响后面的事情 比如:ajax请求 ,nio非阻塞)
四、JAVA内存模型 JMM
我们常说的JVM内存模式指的是JVM的内存分区;而Java内存模式是一种虚拟机规范。
Java虚拟机规范中定义了Java内存模型(Java Memory Model,JMM),用于屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果,JMM规范了Java虚拟机与计算机内存是如何协同工作的:规定了一个线程如何和何时可以看到由其他线程修改过后的共享变量的值,以及在必须时如何同步的访问共享变量。原始的Java内存模型存在一些不足,因此Java内存模型在Java1.5时被重新修订。这个版本的Java内存模型在Java8中仍然在使用。
Java内存模型(不仅仅是JVM内存分区):调用栈和本地变量存放在线程栈上,对象存放在堆上
堆Heap:存对象,分散存储 ,检索效率低于栈 ,线程共享 稳定和静态
方法区:不会变的,静态的数据,类,字符串,静态变量
栈Stack:(活泼)方法,程序运行时的动态信息,内存存在于线程中为某个线程服务,其他无法访问,先进后出,后进先出(子弹夹) 执行效率高
五、死锁、饥饿、活锁
死锁:拿部分资源不释放 阻塞 等待
饥饿:拿不够需要的资源 一直要等待 要关注和补齐
活锁:相互礼让,都不获取资源
六、线程安全
后面将根据这个大纲进行阐述和详解,知识内容是根据网上学习资料进行整理归纳,在此总结做个记录,供大家一起学习和进步,理解不到位的地方还请留言指教,非常感谢!
如果有问题,请在下方评论
想获得更多的学习知识请关注微信公众号:西北码农或扫下方二维码