type
status
date
slug
summary
tags
category
icon
password
Property
Jan 16, 2025 07:59 AM
在复习一些关于java.util.concurrent的知识点的时候,我突然悟出了一些道理,仅供分享。
 
起因:
在粗略看ConcurrentHashMap的源码的时候,我发现了一个注释:
notion image
lost initialization race; just spin
这种技术思想在实现单例模式的时候也有体现:
在这个模式中:
  • 第一次检查(if (instance == null))是为了避免不必要的同步。
  • 第二次检查(if (instance == null))是为了确保只有一个线程能够初始化实例。
  • volatile 关键字用于防止指令重排序,确保其他线程能够看到完全初始化的实例。

“Lost initialization race” 的含义

在多线程环境下,可能会出现以下情况:
  • 线程 A 进入 getInstance() 方法,发现 instance 为 null,于是进入同步块。
  • 线程 A 开始初始化 instance,但在初始化完成之前,线程 B 也进入 getInstance() 方法。
  • 线程 B 发现 instance 仍然为 null(因为线程 A 还没有完成初始化),于是也尝试进入同步块。
  • 由于同步块的互斥性,线程 B 会被阻塞,直到线程 A 完成初始化并释放锁。
在这种情况下,线程 B “丢失了初始化竞争”(lost initialization race),因为它没有抢到初始化的机会。

“Just spin” 的含义

“Just spin” 的意思是,线程 B 在发现 instance 为 null 后,可以选择 自旋等待(spin-wait),而不是立即进入阻塞状态。自旋等待是指线程在一个循环中不断检查条件(例如 instance != null),直到条件满足为止。
自旋等待的优点是:
  • 避免了线程上下文切换的开销。
  • 在初始化操作很快完成的情况下,自旋等待可能比阻塞更高效。
自旋等待的缺点是:
  • 如果初始化操作耗时较长,自旋等待会浪费 CPU 资源。
  • 在高并发场景下,大量线程自旋等待可能会导致 CPU 使用率飙升。
抛开技术理解不谈,从场景去看这句话的意思是:在初始化过程中,如果某个线程发现它 “丢失了初始化竞争”(即其他线程已经完成了初始化),那么它可以选择 自旋等待(spin),直到初始化完成。再次看完这句话,思考片刻,突然头皮发麻。这不就是我现在的处境吗?在找工作的过程中,如果发现心仪岗位的公司招满了没有了HC(即这个岗位已经完全饱和了),那么我可以选择继续学习等待新的机会,直至找到心仪的岗位为止。
 
思维切换,从哲学视角去看待:做与不做的影响(争锁与不争锁的影响)
  • 行动:通过行动,我们改变了世界的状态,创造了新的可能性。
  • 不行动:通过不行动,我们保留了现状,但也可能错失机会或导致问题的积累。
也就是
  • 做(竞争锁):线程尝试获取锁,可能会成功并继续执行,也可能会失败并进入阻塞或自旋状态。
  • 不做(不竞争锁):线程放弃竞争,可能会导致任务无法完成,或者选择其他路径(如重试、放弃任务等)。
从中不难看出来:
  • 竞争的本质:锁竞争反映了资源有限性和需求的冲突。多个线程竞争同一把锁,这不就是现实世界中多人竞争同一份工作吗?
  • 自旋锁的哲学意义:自旋锁体现了一种 平衡 的哲学思想。它既不放弃竞争(避免错失机会),也不过度投入(避免资源浪费)。
 
多年以前,在上初中的时候,就听说过中庸,时至今日,没想到在学习并发锁的知识上,悟出了 中庸之道。
 
 
Linux内核相关知识整理记录英语单词积累
fntp
fntp
多一点兴趣,少一点功利
公告
type
status
date
slug
summary
tags
category
icon
password
Property
Sep 5, 2023 06:04 AM
📝 博客只为了记录我的学习生涯
😎 我的学习目标是成为一名极客
🤖 我热爱开源当然我也拥抱开源
💌 我期待能收到你的Email留言
📧 我的邮箱:stickpoint@163.com
欢迎交流~