Java线程的并发及并行

并发与并行的区别

并发是指多个线程操作同一个资源,不是同时执行,而是交替执行。单核CPU,只不过因为CPU的时间片很短,速度太快,看起来是同时执行。

并行才是真正的同时执行,多核CPU。每个线程使用一个单独的CPU的资源来运行。

并发示意图:
在这里插入图片描述
并行示意图:
在这里插入图片描述
但在多数情况下,我们的即使有多核,也同样存在并行的情况,且存在并行与并发同时存在的情况。

并发概念

Java并发的重要性毋庸置疑,可以最大化的提高计算资源的效率。

并发是多线程交替的访问同一个资源,该资源本身的特点是同一时刻只允许一个线程的访问,那么就存在竞争的问题。同一个资源可以是CPU资源,也可以是内存资源。

临界资源和临界区

临界资源:一般指内存资源,一个时刻只允许一个进程(在java中,是线程)访问,一个线程正在使用临界资源的时候,另一个线程不能使用。临界资源是非可剥夺性资源,即使是操作系统(或JVM)也无法阻止这种资源的独享行为。
临界区:是一种线程中访问临界资源的那段程序代码(注意:是程序代码,不是内存资源了,这就是临界资源与临界区的区别)

我们规定临界区的使用原则(也即同步机制应遵循的准则):“空闲让进,忙则等待,有限等待,让权等待”,分别来解释一下:

  • 空闲让进:临界资源空闲时一定要让进程进入,不发生“互斥礼让”行为。
  • 忙则等待:临界资源正在使用时外面的进程等待。
  • 有限等待:进程等待进入临界区的时间是有限的,不会发生“饿死”的情况。
  • 让权等待:进程等待进入临界区是应该放弃CPU的使用。

什么是线程安全?

如果一个操作序列,不考虑耗时和资源消耗,在单线程执行和多线程执行的情况下,最终得到的结果永远是相同的,则这个操作序列叫做线程安全的。如果存在不相同的概率,则就是非线程安全的。

并发的特性

Java并发模型是围绕并发过程中如何处理原子性、可见性、有序性3个特征设计。因此特性有以下三种:

原子性

原子性:如果一个操作时不可分割的,那就是一个原子操作,也叫这个操作具有原子性。相反的,一个操作时可以分割的(如a++,它实际上是a=a+1),则就是非原子操作;原子操作是线程安全的,非原子操作都是非线程安全的,但是我们可以通过同步技术(lock)或同步数据模型(Concurrent容器等)把非原子操作序列变成线程安全的原子操作。

可见性

可见性:一个变量被多个线程共享,如果一个线程修改了这个变量的值,其它线程能够立即得知这个修改,则我们称这个修改具有可见性。

有序性

Java线程的有序性,表现为两个方面:

  • 在一个线程内部观察,所有操作都是有序的,所有指令按照“串行(as-if-serial,字面意思是“像排了序一样”,as-if-serial的真正含义是不管怎么重排序,一个单线程程序的执行结果都必须相同)” 的方式执行。
  • 在线程间观察,也就是从某个线程观察另一个线程,则所有其他线程都可以交叉并行执行,是正序的,唯一例外的是被同步方法、同步块、volatile等字段修饰的强制同步的代码,需要在线程间保持有序。

更多关于Java多线程的内容,详戳【Java多线程】,其他内容,详戳主页。


版权声明:本文为JSDHBIV原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。