由于临界区的存在, 多线程之间的并发必须收到控制。
并发级别分类:
- 阻塞 (Block) -
- 使用synchronized关键字 / 或者使用重入锁, 得到就是阻塞进程
- 都会试图在执行后续代码前得到临界区的锁,否则挂起等待直到占有所需资源
- 无饥饿 (Starvation-Free)
- 无障碍 (Obstruction-Free)
- 如果两个进程是无障碍执行, 不会因为临界区的问题导致一方被挂起。当发现有其他线程也在该临界区的数据 - 回滚以确保数据安全
- 相对 阻塞 方式 是一种 “乐观”策略
- 使用一致性标记来实现“无障碍”调度
- 无锁 (Lock-Free)
- 必然有一个线程能够在有限步内完成操作离开临界区。
- 所有的线程都能尝试对临界区进行访问,但无锁的并发保证必然有一个线程能够在有限步内完成操作离开临界区。
- 无锁调用中,典型情况为:有一个无限循环,线程在循环中不断尝试修改共享变量;如果无冲突,修改成功-程序退出,否则继续尝试修改。对于临界区中竞争失败的线程, 它们必须不断重试直到自己获胜;如果总是失败, 则会出现类似“饥饿”的现象,线程会停止不前。
- 无等待 (Wait-Free)
- 所有的线程都必须在有限布内完成操作 - 这样不会引起饥饿问题。
- 有界无等待
- 线程数无关的无等待
- RCU (Read-Copy-Update)为典型无等待结构。
- 所有读线程都是无等待的
- 写 -先取得原始数据的副本,修改副本数据,合适的时机回写数据。