- 同步(Synchronization)与异步(Asynchronous)
- 并发(Concurrence)与并行(Parallelism)
- 临界区
- 阻塞(Blocking)与非阻塞(Non-Blocking)
- 死锁(Deadlock)、饥饿(Starvation)与活锁(LiveLock)
- 原子性(Atomicity)
- 可见性(Visibility)
- 有序性
- 内存屏障(memory barriers)
- 原子操作(atomic operations)
- 缓冲行(cache line)
- 缓冲行填充(cache line fill)
- 缓存命中(cache hit)
- 写命中(write hit)
- 写缺失(write miss the cache)
同步(Synchronization)与异步(Asynchronous)
- 同步:顺序执行语句或函数。只有当上一个函数执行完毕,才能继续往下执行
- 异步:在Java中,通过多线程完成异步操作。异步则是新建立一个线程,在线程中执行语句或函数,原来的线程还在继续运行,当新线程执行完毕时,可以进一步通知别的线程它的执行结果
并发(Concurrence)与并行(Parallelism)
两者都表示多个任务一起执行。其中:
- 并发:任务交替执行(分发时间片进行交替执行)
- 并行:任务同时执行(多核CPU环境)
临界区
表示一种资源或数据,可以同时被多个线程使用。在并发编程中,临界区就是需要保护的对象。
阻塞(Blocking)与非阻塞(Non-Blocking)
- 阻塞:多个线程争夺同一个临界区资源,当其中一个线程获取到该资源而导致其他线程挂起的现象
- 非阻塞:一个线程并不能影响其他线程的执行称为非阻塞
死锁(Deadlock)、饥饿(Starvation)与活锁(LiveLock)
- 死锁:线程之间占据了彼此的资源导致彼此挂起等待的现象;
- 饥饿:一个线程久久无法获取到所需资源的情况;
- 活锁:线程之间主动释放资源给彼此,导致资源在彼此之间跳动的现象
原子性(Atomicity)
指一个不可中断的操作。即使在多线程环境,一个原子操作一旦开始,其他线程就不能进行干扰。
注意:在32位机上读写double类型数据和long类型数据不是原子操作,因为两者的存储会占据两个相邻的4字节空间,每一次读写都是两个读写内存的操作。在多线程环境中,可能会导致异常结果。
可见性(Visibility)
指一个线程修改了某个共享变量时,其他线程能够马上知道这次的修改。
有序性
在指令重排序的情况下,执行指令与原指令的执行顺序不一致的现象。
内存屏障(memory barriers)
一组处理器指令,用于实现对内存操作的顺序限制。
原子操作(atomic operations)
缓冲行(cache line)
缓存中可以分配的最小存储单位。处理器填写缓存行时会自动加载整个缓存行,需要多个主内存读周期。
缓冲行填充(cache line fill)
当 CPU 识别到从内存中读取操作数是可缓存的,处理器读取整个缓存行到适当的缓存。
缓存命中(cache hit)
如果进行高速缓存行填充操作的内存位置仍是下次处理器访问的地址时,处理器从缓存中读取操作数,而不是从内存读写。
写命中(write hit)
当 CPU 将操作数写入到一个内存区域时,它首先会检查这个内存的地址是否在缓存行中,如果存在一个有效的缓存行,则处理器将这个操作数写入缓存行,而不是写回内存。这个操作称之为写命中。
写缺失(write miss the cache)
一个有效的缓存行被写入到一个不存在的内存区域。