必须知道的几个概念
同步(Synchronous)和异步(Asynchronous)
同步方法调用一旦开始,调用者必须等待方法调用返回后才能继续后续行为。异步方法调用更像一个消息传递,一旦开始就立即返回,调用者就可以继续后续的操作。而被调用的异步方法会在另外一个线程里真实地执行。如果异步调用需要返回结果,那么当这个调用真实完成的时候,则会通知调用者。
并发(Concurrency)和并行(Parallelism)
这两个概念非常容易被混淆,它们都可以表示多个任务一起执行,但并发偏重于多个任务交替执行,而多个任务之间可能还是串行,让外部的观察者看起来像是并行;而并行是真正意义上的同时执行。
实际上,如果系统内只有一个单核 CPU,那么多线程或者多进程任务不可能是真实并行的,毕竟一个 CPU 一次只能执行一条指令,这样只能叫做并发而不是并行;真实的并行只可能出现在多个单核和/或者多核 CPU 中。
临界区
临界区表示一种公共资源,可以被多个线程使用。但是每一次只能有一个线程使用它,一旦临界区资源被占用,其他线程想要使用它就必须等待。
阻塞(Blocking)和非阻塞(Non-Blocking)
通常用来形容多个线程之间的相互影响。比如一个线程占用了临界区资源,那么其他所有需要这个资源的线程就必须等待,直到这个线程释放了这个资源。这种情况就是阻塞;非阻塞代表没有一个线程可以妨碍其他线程执行,所有的现成都会尝试不断执行下去。
死锁(Deadlock)、饥饿(Starvation)和活锁(Livelock)
多个线程占有了其每个线程都需要的资源,你不让我我不让你,造成程序无法继续执行下去,这就是死锁;饥饿是指某个或多个线程一直等不到所需的资源导致一直无法执行,或者一个线程一直占有资源不释放,其余线程一直在尝试获取这个资源;活锁是指每个线程都主动地将资源释放给别人用,那么就没有任何一个线程能够顺利占有这个资源执行。
并发级别
阻塞(Blocking)
一个线程是阻塞的,那么在其他线程释放之前,这个线程是无法执行的。
无饥饿(Starvation-Free)
如果锁是公平的,不管新来的线程优先级有多高,想要获得资源,也必须排队等待前面有可能优先级比较低的先使用资源,这样所有的线程都有机会执行。
无障碍(Obstr-Free)
多个进程可以一起进入临界区获取资源。为了避免在资源被多个线程修改导致一致性问题发生,其每个线程会在修改资源后进行回滚操作确保数据安全。但是依然会有一个问题就是资源修改的冲突特别大的时候,会导致每个线程一直在回滚,没有一个线程能够走出临界区。
无锁(Lock-Free)
无锁的并行都是无障碍的,但不同的是无锁的并发保证了必然有一个线程能够在有限步骤内离开临界区。
无等待(Wait-Free)
无等待是要求所有的无障碍线程必须全部在有限步骤内离开临界区,这样就不会遇到饥饿问题。
有关并行的两个重要定律
(未完待续)
实战 Java 高并发程序设计 第一章 走入并行世界 读书笔记
欢迎加入咖啡馆的春天(338147322)。