几个重要的概念
同步(synchronous)和异步(asynchronous)
同步和异步通常用来形容一次方法调用。
- 同步方法调用一旦开始,调用者必须等到方法调用返回后,才能继续后续的行为。
- 异步方法调用更像一个消息传递,一旦开始,方法调用就会立即返回,调用者就可以继续后续的操作。而且异步方法通常会在另外一个线程中,“真实”地执行着。整个过程,不会阻碍调用者的工作。
并发(Concurrency)和并行(Parallelism)
并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生。
临界区
临界区用来表示一种公共资源或者说是共享数据,可以被多个线程使用。但是每一次,只能有一个线程
使用它,一旦临界区资源被占用,其他线程要想使用这个资源,就必须等待。
阻塞(Blocking)和非阻塞(Non-Blocking)
阻塞和非阻塞通常用来形容多线程间的相互影响。比如一个线程占用了临界区资源,那么其它所有需要
这个资源的线程就必须在这个临界区中进行等待,等待会导致线程挂起。这种情况就是阻塞。
此时,如果占用资源的线程一直不愿意释放资源,那么其它所有阻塞在这个临界区上的线程都不能工作。
非阻塞允许多个线程同时进入临界区
死锁(Deadlock)、饥饿(Starvation)和活锁(Livelock)
死锁、饥饿和活锁都属于多线程的活跃性问题,如果出现上述几种情况,那么相关线程可能就不再活跃,也就很难再继续执行下去。
- 死锁:两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁
产生死锁的四个必要条件:
(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系。
循环等待导致死锁产生
- 饥饿:一个或者多个线程因为种种原因无法获得所需要的资源,导致一直无法执行。如,线程优先级太低或者某一个线程一直占着关键资源不放,需要这个资源的线程无法正常执行。与死锁相比,饥饿是有可能在未来一段时间内解决的(比如高优先级的线程已经完成任务,不再执行)。
- 活锁:活锁指的是任务或者执行者没有被阻塞,由于某些条件没有满足,导致一直重复尝试—失败—尝试—失败的过程。处于活锁的实体是在不断的改变状态,活锁有可能自行解开。(当两个线程秉承“谦让”原则,主动将资源释放给对方使用,那么就会出现资源不断在两个线程中跳动,而没有一个线程可以拿到所有资源而正常执行。这种情况就是活锁。)
并发级别
阻塞(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为串行百分比任务。