深究多线程底层原理 - 持续更新

volatile

  1. 作用: 被 volatile 修饰的变量值在变化时,会被所有线程感知到.保证了多线程模型的可见性;
  2. 应用: 大量应用于 JDK 已有类型如 concurent, atomic 包下;
  3. 原理:
    1. 编译层面: 内存屏障防止指令重排序, 保证有序性;
    2. 执行层面: 被 volatile 修饰的变量在汇编语言执行时,会在语句前缀加上 lock ,从而依托多核 CPU 的缓存一致性协议 MESI 修改 互斥 共享 , 无效) ,当 总线 中的值修改时, 多个 CPU 可以同时立刻嗅探到修改操作( 总线嗅探机制 ), 并在缓存行变化成共享状态前将修改后的值记录回来,从而立刻感知到被 volatile 修改后的值, 保证可见性;
  4. 失效场景:  var++; // 自增操作实际如下
    int temp = var;
    var = var + 1;
  5. 可用场景: boolean 类型
  6. 性能对比: 优于 lock,synchronized

指令重排序

  1. 重排序场景: 编译期重排序, 处理器重排序, 内存系统重排序
  2. 什么时候不会重排序优化: 
    1. as-if-serial:
      1. 单线程程序指令间操作数据存在依赖关系,可能会导致重排序,数据间无依赖关系则不会影响执行结果
    2. happens-before: 开始于 JDK5 ,JSR133内存模型
      1. 语义串行: 同 as-if-serial;
      2. 锁: 加锁先于解锁;
      3. volatile: 编译期内存屏障保证不重排, 执行时 MESI 保证可见;
      4. 线程启动: start() 先于线程内代码
      5. 线程中断: 先 interrupt 后被检测到线程中断
      6. 线程终止: join() 后于线程内代码
      7. 对象终结: 构造方法先于终结方法 finalize
      8. 传递性: 语义的串行具有传递性, a 得到 b, b 得到 c, 则 a 必然先于 c;
  3. 如何避免出现意料之外的指令重排序
    1. volatile: 保证修改立即可见, 避免更新丢失
    2. lock加锁: 保证线程安全
    3. 多线程执行时,若线程间数据有有依赖,需要正确使用 volatile 或 lock 锁保证程序逻辑按照设计初衷执行;

对象半初始化问题

  1. 对象如何初始化: ①类加载检查②开辟空间(一块未赋值的地址)③赋默认初始值④设置对象头⑤C++实现的 init 方法为对象赋值
    1. 对象头(基于HotSpot虚拟机): 
      1. ObjectHeader (64位对象头)
        1. 锁状态
          1. 无锁
          2. 偏向锁
          3. 轻量级锁
          4. 重量级锁
          5. GC 标志
        2. 类元数据指针 - 可知对象从哪个类得来
        3. 对象的哈希码
        4. 哪个线程持有锁 - 线程 id
      2. InstanceData 实例信息
      3. PaddingData 对齐补充
  2. 为何会对象半初始化:
    1. 指令重排序 - 当前线程可以先返回拿到地址的对象, 而该对象还未被 init 值,即还未真实赋值
    2. 什么时候重排序 - 超高并发访问同一对象的加载
  3. 怎么解决:
    1. 是不是我连对象都不能 new 了? 除非超高并发访问同一对象的初始化时可能会导致半初始化,否则不会
    2. 懒加载对象双检索初始化单例, 最好给对象添加 volatile 修饰,保证对象的初始化不会被重排;

  • 27
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
回答: RabbitMQ是一种功能强大的消息中间件,它基于AMQP协议,具有简单易用、高并发性能好等特点。\[1\]RabbitMQ使用Erlang语言实现,这也是其高并发性能好的原因之一。它还有一个方便的管理工具,可以用来查看RabbitMQ的运行状态和详细数据等。\[2\]RabbitMQ是消息中间件的一种实现,市面上还有其他实现,如ActiveMQ、ZeroMQ、Kafka和RocketMQ等。\[3\]关于RabbitMQ的高级底层原理,具体包括消息的路由、交换机、队列和绑定等概念。消息通过交换机进行路由,然后被发送到相应的队列中。绑定是交换机和队列之间的关联关系,它决定了消息如何从交换机路由到队列。RabbitMQ还支持多种交换机类型,如直连交换机、主题交换机和扇形交换机,可以根据不同的需求选择合适的交换机类型。此外,RabbitMQ还支持消息的持久化、消息的确认机制和消息的优先级等高级特性。总之,RabbitMQ的高级底层原理涉及到消息的路由、交换机、队列、绑定和一些高级特性的实现。 #### 引用[.reference_title] - *1* [消息中间件架构体系 - 深究“RabbitMQ”及其 底层原理](https://blog.csdn.net/m0_67645544/article/details/123686963)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [RabbitMq底层原理分析](https://blog.csdn.net/qq_40708830/article/details/89454188)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值