这是我参与8月更文挑战的第30天,活动详情查看:8月更文挑战
生产者消费者的晋升
- 这一节我们会使用
Disruptor框架来实现 - 首先还是实体类,代表数据对象
- 来看消费者,是实现了
WorkHandler接口- 主要进行数据的读取和处理,被封装在了
Disruptor框架中
- 主要进行数据的读取和处理,被封装在了
- 我们还需要创建一个AData的工厂类,在框架初始化的时候,会构造出所有的缓冲区中的对象实例
/**
* @Author: xiaoff
* @Date: 2021/8/26 08:52
*/
public class ADataFactory implements EventFactory<AData>{
public AData new instance() {
return new AData();
}
}
- 来看生产者,其中的RingBuffer就是一个环形的缓冲区
- 主要将产生的数据放入缓冲区中
- ByteBuffer就是用来装载或者包装任何一种数据类型
- 本文中用到的是
long类型 - next是得到下一个可用的序列号
/**
* @Author: xiaoff
* @Date: 2021/8/26 23:54
*/
public class Producer {
private final RingBuffer<AData> ringBuffer;
public Producer(RingBuffer<AData> ringBuffer) {
this.ringBuffer =ringBuffer;
}
// 用来接收ByteBuffer对象
public void PushData(ByteBuffer bf) {
// 拿到下一个数据/任务的序列号
long next = ringBuffer.next();
AData data = ringBuffer.get(next);
// 放入数据
data.setValue(bf.getLong(0));
// 放入环形缓冲区
ringBuffer.publish(next);
}
}
伪共享问题
- 为了提高CPU的速度,往往会提到高速缓存Cache
- Cache读写数据的最小单位是缓存行
- 它是从主存复制到缓存的最小单位
- 一般是32字节~128字节
- 当两个变量存在一个缓存行的时候
- 多线程访问的时候,可能会彼此影响性能
- 假设X Y在同一个缓存行
- CPU1更新了X,CPU2上的缓存行就会失效
- 如果反过来也是如此
- 为了避免以上的情况,可以在变量X的前后恐案件先占一定的位置
- 当内存被读入缓存的时候,变量X就会有效
- 不会导致多个线程修改缓存行中的不同变量导致变量全体失效