Disruptor十三问之六伪共享
摘要:这张图说明了伪共享的问题:在核心1上运行的线程想更新变量X,同时核心2上的线程想要更新变量Y。不幸的是,这两个变量在同一个缓存行中。每个线程都要去竞争缓存行的所有权来更新变量。如果核心1获得了所有权,缓存子系统将会使核心2中对应的缓存行失效。当核心2获得了所有权然后执行更新操作,核心1就要使自己对应...
阅读全文
posted @
2015-03-25 19:56
xuqiyu
阅读(238)
推荐(0) 编辑
Disruptor十三问之五内存屏障
摘要:什么是内存屏障?它是一个CPU指令。它是这样一条指令: a)确保一些特定操作执行的顺序; b)影响一些数据的可见性(可能是某些指令执行后的结果)。插入一个内存屏障,相当于告诉CPU和编译器先于这个命令的必须先执行,后于这个命令的必须后执行。强制更新一次不同CPU的缓存。例如,一个写屏障会把这个屏障前...
阅读全文
posted @
2015-03-25 19:46
xuqiyu
阅读(227)
推荐(0) 编辑
Disruptor十三问之四为什么这么快
摘要:Disruptor相对于传统方式的优点:没有竞争=没有锁=非常快。所有访问者都记录自己的序号的实现方式,允许多个生产者与多个消费者共享相同的数据结构。在每个对象中都能跟踪序列号(ring buffer,claim Strategy,生产者和消费者),加上神奇的缓存行填充,就意味着没有为伪共享和非预期...
阅读全文
posted @
2015-03-25 16:07
xuqiyu
阅读(127)
推荐(0) 编辑
Disruptor十三问之三CPU缓存行填充
摘要:64位处理器缓存行的长度是64字节,java 64位long类型数据是8字节,也就是说一个缓存行需要8个long类型数据填充如上图,假设volatile类型 head和tail在内存中地址连续,被两个CPU core1和core2都加载到各自的缓存行中,如果core1修改了head的值(缓存和内存中...
阅读全文
posted @
2015-03-24 17:39
xuqiyu
阅读(341)
推荐(0) 编辑
Disruptor十三问之二Volatile
摘要:Volatile变量修饰符如果使用恰当的话,它比synchronized的使用和执行成本会更低,因为它不会引起线程上下文的切换和调度。处理器为了提高处理速度,不直接和内存进行通讯,而是先将系统内存的数据读到内部缓存(L1,L2或其他)后再进行操作,但操作完之后不知道何时会写到内存,如果对声明了Vol...
阅读全文
posted @
2015-03-24 17:17
xuqiyu
阅读(164)
推荐(0) 编辑
Disruptor十三问之一RingBuffer
摘要:并发框架Disruptor使用了一个叫做 RingBuffer(环)的数组结构它只有指向下一个可用位置的序号,没有只向尾部的序号,是因为RingBuffer不删除Buffer中的数据,当重叠时直接用新数据覆盖。为什么使用数组而不是链表,1.数组在内存的存储位置是连续的,链表是不连续的。对数组的访问比...
阅读全文
posted @
2015-03-24 16:36
xuqiyu
阅读(304)
推荐(0) 编辑
HashMap 死循环 CPU100%的问题分析
摘要:之前看过左耳朵耗子的博客,我自己再把这个问题重新整理一遍1.HashMap表的数据结构HashMap用一个指针数组来存储Entry, 按照Entry的key通过一定的规则(得到哈希值)来分散存储这些元素,假设摸一个Entry(B)当按照这个规则计算出来的下标位置已有一个Entry(A),会将最新的E...
阅读全文
posted @
2015-03-23 16:38
xuqiyu
阅读(530)
推荐(0) 编辑