架构师养成记--16.disruptor并发框架中RingBuffer的使用
很多时候我们只需要消息中间件这样的功能,那么直需要RinBuffer就可以了。
入口:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; import com.lmax.disruptor.BatchEventProcessor;
import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.SequenceBarrier;
import com.lmax.disruptor.YieldingWaitStrategy; public class Main1 { public static void main(String[] args) throws Exception {
int BUFFER_SIZE=1024;
int THREAD_NUMBERS=4;
/*
* createSingleProducer创建一个单生产者的RingBuffer,
* 第一个参数叫EventFactory,从名字上理解就是"事件工厂",其实它的职责就是产生数据填充RingBuffer的区块。
* 第二个参数是RingBuffer的大小,它必须是2的指数倍 目的是为了将求模运算转为&运算提高效率
* 第三个参数是RingBuffer的生产都在没有可用区块的时候(可能是消费者(或者说是事件处理器) 太慢了)的等待策略
*/
final RingBuffer<Trade> ringBuffer = RingBuffer.createSingleProducer(new EventFactory<Trade>() {
@Override
public Trade newInstance() {
return new Trade();
}
}, BUFFER_SIZE, new YieldingWaitStrategy()); //创建线程池
ExecutorService executors = Executors.newFixedThreadPool(THREAD_NUMBERS); //创建SequenceBarrier
SequenceBarrier sequenceBarrier = ringBuffer.newBarrier(); /****************** @beg 消费者消费数据 2017-1-11******************/
//创建消息处理器
BatchEventProcessor<Trade> transProcessor = new BatchEventProcessor<Trade>(
ringBuffer, sequenceBarrier, new TradeHandler()); //这一步的目的就是把消费者的位置信息引用注入到生产者 如果只有一个消费者的情况可以省略
ringBuffer.addGatingSequences(transProcessor.getSequence()); //把消息处理器提交到线程池
executors.submit(transProcessor);
/****************** @end 消费者消费数据 2017-1-11******************/ //如果存在多个消费者 那重复执行上面3行代码 把TradeHandler换成其它消费者类 /****************** @beg 生产者生产数据 2017-1-11******************/ Future<?> future= executors.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
long seq;
for(int i=0;i<10;i++){
seq = ringBuffer.next();//占个坑 --ringBuffer一个可用区块
ringBuffer.get(seq).setPrice(Math.random()*9999);//给这个区块放入 数据
ringBuffer.publish(seq);//发布这个区块的数据使handler(consumer)可见
}
return null;
}
}); /****************** @end 生产者生产数据 2017-1-11******************/ future.get();//等待生产者结束
Thread.sleep(1000);//等上1秒,等消费都处理完成
transProcessor.halt();//通知事件(或者说消息)处理器 可以结束了(并不是马上结束!!!)
executors.shutdown();//终止线程
}
}
消费者:
import java.util.UUID; import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.WorkHandler; public class TradeHandler implements EventHandler<Trade>, WorkHandler<Trade> { @Override
public void onEvent(Trade event, long sequence, boolean endOfBatch) throws Exception {
this.onEvent(event);
} @Override
public void onEvent(Trade event) throws Exception {
//这里做具体的消费逻辑
event.setId(UUID.randomUUID().toString());//简单生成下ID
System.out.println(event.getId());
}
}
数据对象:
import java.util.concurrent.atomic.AtomicInteger; public class Trade { private String id;//ID
private String name;
private double price;//金额
private AtomicInteger count = new AtomicInteger(0); public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public AtomicInteger getCount() {
return count;
}
public void setCount(AtomicInteger count) {
this.count = count;
} }
架构师养成记--16.disruptor并发框架中RingBuffer的使用的更多相关文章
- 架构师养成记--15.Disruptor并发框架
一.概述 disruptor对于处理并发任务很擅长,曾有人测过,一个线程里1s内可以处理六百万个订单,性能相当感人. 这个框架的结构大概是:数据生产端 --> 缓存 --> 消费端 缓存中 ...
- 架构师养成记--35.redis集群搭建
前记:redis哨兵经验之谈.哨兵做主从切换可能要花费一两秒,这一两秒可能会丢失很多数据.解决方法之一是在java代码中做控制,try catch 到 链接断开的异常就sleep 一两秒钟再conti ...
- 架构师养成记--10.master-worker模式
master-worker模式是一种并行计算模式,分为master进程和worker进程两个部分,master是担任总管角色,worker才是执行具体任务的地方. 总体流程应该是这样的: 具体一点,代 ...
- 架构师养成记--8.Queue
一.ConcurrentLinkedQueue 是一个适合在高并发场景下,无锁,无界的,先进先出原则.不允许为null值,add().offer()加入元素,这两个方法没区别:pull().peek( ...
- 架构师养成记--32.Redis高级(安全 主从复制)
Redis高级命令及特性 keys * 返回满足的所有键值(*表示模糊匹配) exists 是否存在指定的key(返回1表示存在,0表示不存在) expire 设置某个key的过期时间,使用ttl查看 ...
- 架构师养成记--29.redis开篇
主要有从下几点讲解 NOSQL(Redis) 简介.redis安装与部署 Redis基础事件类型详解 Redis高级命令 Redis与java的使用 Redis集群搭建 Redis集群与spring的 ...
- 架构师养成记--21.netty编码解码
背景 作为网络传输框架,免不了哟啊传输对象,对象在传输之前就要序列化,这个序列化的过程就是编码过程.接收到编码后的数据就需要解码,还原传输的数据. 代码 工厂类 import io.netty.han ...
- 架构师养成记--19.netty
一.Netty初步 为什么选择Netty? 和NIO比较,要实现一个通信要简单得很多,性能很好.分布式消息中间件.storm.Dubble都是使用Netty作为底层通信. Netty5.0要求jdk1 ...
- 架构师养成记--17.disrunptor 多生产者多消费者
入口: import java.nio.ByteBuffer; import java.util.UUID; import java.util.concurrent.CountDownLatch; i ...
随机推荐
- opennebula 补丁制作与补丁升级
参考文章:http://www.cnblogs.com/itech/archive/2009/08/19/1549729.htmlhttp://www.ibm.com/developerworks/c ...
- IPMI (Intelligent Platform Management Interface)
4.3. ipmitool - utility for controlling IPMI-enabled devices 4.3.1. ipmitool 4.3.1.1. ubuntu 确定硬件是否支 ...
- xshell上传下载文件(Windows、Linux)
经常有这样的需求,我们在Windows下载的软件包,如何上传到远程Linux主机上?还有如何从Linux主机下载软件包到Windows下:之前我的做法现在看来好笨好繁琐,不过也达到了目的,笨人有本方法 ...
- c11时间库一个小例子
#pragma once #include <chrono> #include <string> #include <iostream> #include < ...
- velocity在html中换行符转换
<td colspan="3" class="tdContent2">$!obj.getDealInfo().replaceAll("\r ...
- 基于Web Service的客户端框架搭建四:终结篇
前言 这是这个系列的终结篇,前面3个博客介绍了一下内容: 1.使用Http Post方式调用Web Service 2.客户端框架之数据转换层 3.客户端框架之代理层 框架结构 框架是基于C#的,在V ...
- oj 1002题 (大数题)
#include <stdio.h> #include <string.h> int main(void) { int q,j,h,k,l; int d; ],s2[];//题 ...
- QQ互联
[移动应用接入概述] QQ互联开放平台为第三方移动应用提供了丰富的API.第三方移动应用接入QQ互联开放平台后,即可通过调用平台提供的API实现用户使用QQ账号登录移动应用功能,且可以获取到腾讯QQ用 ...
- 马婕 2014MBA专硕考试报刊选读 5 朱令案悬而未决引起全社会的关注(转)
http://blog.sina.com.cn/s/blog_3e66af4601016pkh.html Why hasn’t doubt over poisoning subsided? 公众对于朱 ...
- EBS11i - 常用Profile
Profile Name 说明 设置建议 FND: Enable Cancel Query 当执行一个超长时间的查询时,会出现一个 Cancel窗口,允许用户取消.比如我们在SO 界面没有输入条件 ...