并发和并行
- 并发:在同一时间段内,多个任务同时执行,偏向于多个任务交替执行,在某一时刻其实只有一个任务在执行(单个CPU就可并发,比如时间片轮转机制)。
- 并行:同一时刻,多个任务同时执行(并行需要有多个CPU)。
临界区
- 临界区:用来形容一种共享资源,可以被多个线程访问,但是一次仅允许一个线程使用。
同步和异步
常用于形容一次方法调用。
- 调用了同步方法后,调用者会等待方法返回,再继续后续行为(未开启新线程,串行执行)。
- 调用了异步方法后,方法立即返回,调用者可继续执行后续行为,不需要耗时等待异步方法的执行(开启一个新的线程去执行异步方法)。
阻塞和非阻塞
是指调用者在等待调用结果(消息,返回值)时的状态,阻塞是指调用结果返回之前,当前线程会被挂起。非阻塞指在不能立刻得到结果之前,该调用不会阻塞当前线程
当临界区资源被别的线程占用时,当前线程就会等待资源的释放,线程挂起并进入阻塞状态。
一个简单的例子
部门团建去KTV唱歌,一个房间只带一个卫生间(临界区资源),同一时刻只允许一个人使用,A在使用时,会将门锁上(加锁),房间里其他人想要使用卫生间就需要等待(阻塞状态),A使用完后开锁(解锁),此时外面的人就可以进去。
死锁、饥饿和活锁
- 死锁:多个并发进程因争夺系统资源而产生无止境的相互等待现象。
产生死锁的4个必要条件:
1.互斥: 某种资源一次只允许一个进程访问,即该资源一旦分配给某个进程,其他进程就不能再访问,直到该进程访问结束。
2.占有且等待: 一个进程本身占有资源(一种或多种),同时还有资源未得到满足,正在等待其他进程释放该资源。
3.不可抢占: 别人已经占有了某项资源,你不能因为自己也需要该资源,就去把别人的资源抢过来。
4.循环等待: 存在一个进程链,使得每个进程都占有下一个进程所需的至少一种资源。
- 饥饿:是指某个线程由于某些原因一直无法获得资源,导致一直不能执行。比如,线程优先级太低了,持续有优先级高的线程插队,导致无法执行。
- 活锁:线程都主动释放资源给他人使用,导致资源在线程之间来回跳动,却始终没有一个线程能获取到他所需的全部资源。
并发级别
- 阻塞:悲观策略,等不到资源,就将当前线程挂起,进入阻塞状态,直到占有所需资源为止。
- 无饥饿:悲观策略,公平锁就没有优先级之分,不存在“插队”的现象,所有线程都有机会执行。
- 无障碍:乐观策略,所有线程都无障碍的执行,一起修改共享数据。修改共享数据时会维护“一致性标记”,通过标记来识别这个共享数据是否出现修改冲突,如果冲突就回退。但是,当临界区出现严重冲突时,所有线程都不断回滚自己的操作,没有一个线程可以走出临界区。
- 无锁:乐观策略,无锁是在无障碍的基础上,保证必然有一个线程能在有限步骤内完成操作,离开临界区。
- 无等待:乐观策略,无等待是在无锁的基础上,保证必然所有线程都能在有限步骤内完成操作。