多线程并发时,如果一个线程是阻塞的,那么其他线程在阻塞线程释放资源之前必须等待。
当使用synchronized或者重入锁时得到的就是阻塞的线程。
没有得不到执行的线程。
如果一个资源分配是公平的,比如按照顺序分配,就是无饥饿的;如果是不公平的,比如高优先级的可以插队执行,则有可能产生饥饿线程,长时间得不到执行。
无障碍是一种最弱的非阻塞调度,最弱是指相对于其他的非阻塞调度,它的非阻塞“能力“,比较弱。
非阻塞调度是一种乐观的策略,它认为多个线程之间发生冲突的概率不大,因此大家都可以无阻塞的进入临界区,但一旦检测到冲突则进行回滚。
当冲突比较严重时,所有的线程都可能不断的回滚自己的操作,而没有一个线程可以走出临界区。
一种可行的方案,“一致性标记”,线程在操作之前,先读取并保存一致性标记,操作完成后,再次读取,检查标记是否被改过,如果不一致则重试操作。而任何对标记进行修改的线程,在修改之前必须先更新标记,表示数据不再安全。
无锁的并行都是无障碍的。
无锁的并发保证必然有一个线程能够在有限步内完成操作离开临界区。
典型特点:可能会包含一个死循环。不断尝试修改共享变量,如果成功则退出。也可能会出现饥饿现象。
无等待比无锁更进一步,无锁只要求有一个线程在有限步内完成操作,而无等待则要求所有的线程都必须在有限步内完成。这就不会引起饥饿问题。
典型的无等待结构是RCU(Read-Copy-Update),对读不加控制,写时先拷贝取得副本,修改副本数据,适时回写数据。