Disrunptor多生产者多消费者模型讲解
多生产者多消费者模拟需求:
1、创建100个订单生产者,每个生产者生产100条订单,总共会生产10000条订单,由3个消费者进行订单消费处理。
2、100个订单生产者全部创建完毕,再一起生产消费订单数据
1、定义事件
package com.ljq.multi;
public class Order {
private String id;// ID
private String name;
private double price;// 金额
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;
}
}
2、生产者
package com.ljq.multi; import com.lmax.disruptor.RingBuffer; /**
* 生产者
*
* @author Administrator
*
*/
public class Producer {
private final RingBuffer<Order> ringBuffer; public Producer(RingBuffer<Order> ringBuffer) {
this.ringBuffer = ringBuffer;
} /**
* onData用来发布事件,每调用一次就发布一次事件 它的参数会用过事件传递给消费者
*/
public void onData(String data) {
// 可以把ringBuffer看做一个事件队列,那么next就是得到下面一个事件槽
long sequence = ringBuffer.next();
try {
// 用上面的索引取出一个空的事件用于填充(获取该序号对应的事件对象)
Order order = ringBuffer.get(sequence);
// 获取要通过事件传递的业务数据
order.setId(data);
} finally {
// 发布事件
// 注意,最后的 ringBuffer.publish 方法必须包含在 finally 中以确保必须得到调用;如果某个请求的
// sequence 未被提交,将会堵塞后续的发布操作或者其它的 producer。
ringBuffer.publish(sequence);
}
} }
3、消费者
package com.ljq.multi;
import java.util.concurrent.atomic.AtomicInteger;
import com.lmax.disruptor.WorkHandler;
public class Consumer implements WorkHandler<Order>{
private String consumerId;
private static AtomicInteger count = new AtomicInteger(0);
public Consumer(String consumerId){
this.consumerId = consumerId;
}
@Override
public void onEvent(Order order) throws Exception {
count.incrementAndGet();
System.out.println("当前消费者: " + this.consumerId + ",消费信息:" + order.getId() + ",count:" + getCount());
}
public int getCount(){
return count.get();
}
}
4、生产者消费者启动类
package com.ljq.multi; import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger; import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.ExceptionHandler;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.SequenceBarrier;
import com.lmax.disruptor.WorkerPool;
import com.lmax.disruptor.YieldingWaitStrategy;
import com.lmax.disruptor.dsl.ProducerType; /**
* disrunptor 多生产者多消费者
*
* @author Administrator
*
*/
public class Main { public static void main(String[] args) throws Exception { //创建ringBuffer
RingBuffer<Order> ringBuffer =
RingBuffer.create(ProducerType.MULTI,
new EventFactory<Order>() {
@Override
public Order newInstance() {
return new Order();
}
},
1024 * 1024,
new YieldingWaitStrategy()); SequenceBarrier barriers = ringBuffer.newBarrier(); //创建3个消费者消费订单数据
Consumer[] consumers = new Consumer[3];
for(int i = 0; i < consumers.length; i++){
consumers[i] = new Consumer("c" + i);
} WorkerPool<Order> workerPool =
new WorkerPool<Order>(ringBuffer,
barriers,
new IntEventExceptionHandler(),
consumers); ringBuffer.addGatingSequences(workerPool.getWorkerSequences());
workerPool.start(Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())); final AtomicInteger count = new AtomicInteger(0);
final CountDownLatch latch = new CountDownLatch(1);
//100个生产者
for (int i = 0; i < 100; i++) {
final Producer p = new Producer(ringBuffer);
new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(count.incrementAndGet());
latch.await(); //等待,直到100个生产者创建完成,再一起生产消费订单数据 } catch (InterruptedException e) {
e.printStackTrace();
} //每个生产者生产100条订单
for(int j = 0; j < 100; j ++){
p.onData(UUID.randomUUID().toString());
}
}
}).start();
}
System.out.println("---------------开始生产-----------------"); latch.countDown(); //生产者全部创建完毕,开始生产订单 } static class IntEventExceptionHandler implements ExceptionHandler {
public void handleEventException(Throwable ex, long sequence, Object event) {}
public void handleOnStartException(Throwable ex) {}
public void handleOnShutdownException(Throwable ex) {}
}
}
Disrunptor多生产者多消费者模型讲解的更多相关文章
- 【java线程系列】java线程系列之线程间的交互wait()/notify()/notifyAll()及生产者与消费者模型
关于线程,博主写过java线程详解基本上把java线程的基础知识都讲解到位了,但是那还远远不够,多线程的存在就是为了让多个线程去协作来完成某一具体任务,比如生产者与消费者模型,因此了解线程间的协作是非 ...
- Java线程(学习整理)--4---一个简单的生产者、消费者模型
1.简单的小例子: 下面这个例子主要观察的是: 一个对象的wait()和notify()使用情况! 当一个对象调用了wait(),那么当前掌握该对象锁标记的线程,就会让出CPU的使用权,转而进入该对 ...
- Python之生产者&、消费者模型
多线程中的生产者和消费者模型: 生产者和消费者可以用多线程实现,它们通过Queue队列进行通信. import time,random import Queue,threading q = Queue ...
- Spring MVC 使用介绍(七)—— 注解式控制器(三):生产者与消费者模型
一.MIME类型 MIME类型格式:type/subtype(;parameter)? type:主类型,任意的字符串,如text,如果是*号代表所有 subtype:子类型,任意的字符串,如html ...
- 守护进程,互斥锁,IPC,队列,生产者与消费者模型
小知识点:在子进程中不能使用input输入! 一.守护进程 守护进程表示一个进程b 守护另一个进程a 当被守护的进程结束后,那么守护进程b也跟着结束了 应用场景:之所以开子进程,是为了帮助主进程完成某 ...
- python queue和生产者和消费者模型
queue队列 当必须安全地在多个线程之间交换信息时,队列在线程编程中特别有用. class queue.Queue(maxsize=0) #先入先出 class queue.LifoQueue(ma ...
- python并发编程之守护进程、互斥锁以及生产者和消费者模型
一.守护进程 主进程创建守护进程 守护进程其实就是'子进程' 一.守护进程内无法在开启子进程,否则会报错二.进程之间代码是相互独立的,主进程代码运行完毕,守护进程也会随机结束 守护进程简单实例: fr ...
- 人生苦短之我用Python篇(队列、生产者和消费者模型)
队列: queue.Queue(maxsize=0) #先入先出 queue.LifoQueue(maxsize=0) #last in fisrt out queue.PriorityQueue( ...
- python:生产者与消费者模型
1,生产者与消费者模型的矛盾在于数据供需的不平衡 import time import random from multiprocessing import Queue from multiproce ...
随机推荐
- 2018/02/25 PendingIntent使用
https://www.cnblogs.com/liyiran/p/4656821.html http://blog.csdn.net/ydpl2007/article/details/7591642 ...
- android-基础编程-ListView
ListView主要包括view和数据源.其数据适配器列表分为三种,ArrayAdapter,SimpleAdapter和SimpleCursorAdapter. ListView的没有oom原因.经 ...
- _ZNote_Qt_对话框_模态非模态
QDialog(及其子类,以及所有Qt::Dialog类型的类)的对于其 parent 指针都有额外的解释:如果 parent 为 NULL,则该对话框会作为一个顶层窗口,否则则作为其父组件的子对话框 ...
- POJ1064--Cable master(Binary Search)
Description Inhabitants of the Wonderland have decided to hold a regional programming contest. The J ...
- dropzone 上传插件
dropzone dropzone.js是一个可预览的上传文件工具,不依赖任何框架(如jQuery),且具有可定制化.实现文件拖拽上传,提供AJAX异步上传功能. 1. html文件 dropzone ...
- Foundation-NSRunLoop
Objective-C之run loop详解 Objective-C之run loop详解 RunLoop 详解
- HBase最佳实践(好文推荐)
HBase最佳实践-写性能优化策略 HBase最佳实践-管好你的操作系统 HBase最佳实践之列族设计优化 [大数据]HBase最佳实践 – 集群规划
- MFC坐标系
MFC坐标系分为设备坐标系和逻辑坐标系两种.在设备坐标系中,一个像素表示一个单位长度,设备的原点(0,0)始终在显示平面的左上角位置,x轴正向向右,y轴正向向下. 逻辑坐标系中,原点可以放在任何一个位 ...
- hbase首次导入大批次的数据成功!
本次主要是采用hbase自带的importtsv工具来导入.首先要把数据文件上传到hdfs上,然后导入hbase表格.该导入方式只支持.tsv数据文件的导入. 导入流程: 1.下载数据.我们在本文中将 ...
- BAE上部署Ghost 0.5.1注意事项
BAE上部署Ghost可参考基本安装上述安装使用的是ghost0.4.7版本 在ghost 0.5 中为了解决测试时事件侦听器过多引发的警告,在注册single事件时,将代码由原先的 process. ...