几个重要的概念

同步(synchronous)和异步(asynchronous)

同步异步通常用来形容一次方法调用。

  • 同步方法调用一旦开始,调用者必须等到方法调用返回后,才能继续后续的行为。
  • 异步方法调用更像一个消息传递,一旦开始,方法调用就会立即返回,调用者就可以继续后续的操作。而且异步方法通常会在另外一个线程中,“真实”地执行着。整个过程,不会阻碍调用者的工作。

Async返回值 java java中async_加速比

 并发(Concurrency)和并行(Parallelism)

并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生。

Async返回值 java java中async_临界区_02

临界区

临界区用来表示一种公共资源或者说是共享数据,可以被多个线程使用。但是每一次,只能有一个线程

使用它,一旦临界区资源被占用,其他线程要想使用这个资源,就必须等待。

Async返回值 java java中async_临界区_03

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

阻塞和非阻塞通常用来形容多线程间的相互影响。比如一个线程占用了临界区资源,那么其它所有需要

这个资源的线程就必须在这个临界区中进行等待,等待会导致线程挂起。这种情况就是阻塞。

此时,如果占用资源的线程一直不愿意释放资源,那么其它所有阻塞在这个临界区上的线程都不能工作。

非阻塞允许多个线程同时进入临界区

死锁(Deadlock)、饥饿(Starvation)和活锁(Livelock)

死锁、饥饿和活锁都属于多线程的活跃性问题,如果出现上述几种情况,那么相关线程可能就不再活跃,也就很难再继续执行下去。

  • 死锁:两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁

产生死锁的四个必要条件:

(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系。

 

Async返回值 java java中async_死锁_04

循环等待导致死锁产生

  • 饥饿:一个或者多个线程因为种种原因无法获得所需要的资源,导致一直无法执行。如,线程优先级太低或者某一个线程一直占着关键资源不放,需要这个资源的线程无法正常执行。与死锁相比,饥饿是有可能在未来一段时间内解决的(比如高优先级的线程已经完成任务,不再执行)。
  • 活锁:活锁指的是任务或者执行者没有被阻塞,由于某些条件没有满足,导致一直重复尝试—失败—尝试—失败的过程。处于活锁的实体是在不断的改变状态,活锁有可能自行解开。(当两个线程秉承“谦让”原则,主动将资源释放给对方使用,那么就会出现资源不断在两个线程中跳动,而没有一个线程可以拿到所有资源而正常执行。这种情况就是活锁。)

并发级别

阻塞(Blocking)

一个线程是阻塞的,那么在其他线程释放资源之前(即当前线程未得到临界区的锁),当前线程无法继续执行(挂起等待)。使用synchronized关键字和重入锁得到的就是阻塞的线程。

无障碍(Obstruction-Free)

无障碍是一种最弱的非阻塞调度。无竞争时,有限步内完成操作。无障碍执行不会因为临界区的问题导致一方被挂起,任何线程都可以进入临界区,修改共享数据。对于无障碍的线程来说,一旦检测到多方同时修改共享数据的情况,它会立即对自己所做的修改进行回滚,确保数据安全。

无锁(Lock-Free)

无锁的并行都是无障碍的,所有线程都能尝试对临界区进行访问。

无等待(Wait-Free)

无等待是一种在无锁的基础上更进一步进行扩展,它要求所有线程都必须在有限步内完成,这样就不会引起饥饿问题。

 有关并行的2个重要定律

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

Amdahl定律(阿姆达尔定律)

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

公式

S=1/(1-a+a/n)

其中,a为并行计算部分所占比例,n为并行处理结点个数。这样,当1-a=0时,(即没有串行,只有并行)最大加速比s=n;当a=0时(即只有串行,没有并行),最小加速比s=1;当n→∞时,极限加速比s→ 1/(1-a),这也就是加速比的上限。

Gustafson定律(古斯塔夫森)

系统优化某部件所获得的系统性能的改善程度,取决于该部件被使用的频率,或所占总执行时间的比例。
说明处理器个数,串行比例和加速比之间的关系
只要有足够的并行化, 那么加速比和CPU个数成正比。

gustafsonl定律定义了加速比:

加速比=采用改进措施前性能/采用改进措施后的性能

=未采用改进措施前执行某任务时间/采用改进措施后执行某任务的时间

W'= n*W 串行部分

+ (1-n)*p*W 并行部分

其中 W 为p个处理器串行+并行时完成任务的时间T2

W‘ 为1个处理器仅串行时完成任务的时间T1

p个处理器加速因子

S = T1 / T2

= W' / W

= n + ( 1-n )*p

n为串行百分比任务。