Java 线程间通讯库 Disruptor
来源:互联网 发布:小米手机怎么迁移数据 编辑:程序博客网 时间:2024/06/08 13:17
Disruptor的具体原理 http://ifeve.com/disruptor/
通过cache line对齐来解决 false sharing的问题,而且是无锁的,应该比java自带的blocking queue速度要快。
这个Disruptor库用来解决生产者和消费者问题,它可以实现生产者和消费者 N:M的关系。
可实现的模式有 菱形(disruptor.handleEventsWith(c0,c1).then(c2) )
*
* +----+
* +----->| C0 |-----+
* | +----+ |
* | v
* +----+ +----+
* | P0 | | C2 |
* +----+ +----+
* | ^
* | +----+ |
* +----->| C1 |-----+
* +----+
*
管道(isruptor.handleEventsWith(c0).then(c1).then(c2))
* +----+ +----+ +----+ +----+
* | P0 |--->| C0 |--->| C1 |--->| C2 |
* +----+ +----+ +----+ +----+
后面的消费者要等到前面的消费者处理完后,才会处理该消息。菱形状态下,C0和C1并发运行,但处理的消息都是一样的。也就是说,一个生产者产生的同一个数据都会被
C0和C1处理,而不会只有C0或者C1处理。并行的意思是C0,C1,C2在不同的线程中。disruptor会为每个消费者分配一个线程。
要注意ringbuffer的分配的大小,ringbuffer不应该太大。如果你需要一个很大的ringbuffer,说明消费者线程这边处理能力不够,需要提高消费者处理线程能力。
当然也有可能是生产者这边burst的比较厉害。消费者消费完数据后,ringbuffer仍旧引用你的数据,导致Jvm无法回收这些内存。如果确实为应对生产者的burst,而
申请一个大的ringbuffer,注意在Evnet中清理数据。这个可以通过加一个消费者,最后一个消费者处理event中引用的数据即可。
MainDisruptor.java
package example1;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.ThreadFactory;import com.lmax.disruptor.BlockingWaitStrategy;import com.lmax.disruptor.dsl.Disruptor;import com.lmax.disruptor.dsl.ProducerType;public class MainDisruptor {public static void main(String[] args) {// TODO Auto-generated method stub//ExecutorService executor = Executors.newFixedThreadPool(1);Disruptor<LogEvent> disruptor = new Disruptor<LogEvent>(new MyFactory(), 4, new ThreadFactory() {@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(r);System.out.println("create new thread " + t.getId());return t;}}, ProducerType.SINGLE,new BlockingWaitStrategy());new MyEventHandler(0);//产生三个消费者线程disruptor.handleEventsWith( new MyEventHandler(0), new MyEventHandler(1) ).then( new MyEventHandler(3));disruptor.start();for(int i=0; i<10; i++) {MyData data = new MyData();data.orderID = i;data.price = Math.random();disruptor.publishEvent( new MyEventTranslatorOneArg(), data);}disruptor.shutdown();}}
LogEvent.java
public class LogEvent {private MyData data;public void setValue(MyData data) {this.data = data;}public MyData getData() {return this.data;}public String toString() {return "LogEvent";}}
MyData.java
public class MyData {public int orderID;public double price;public String toString() {return String.format("orderID %d, price %f", orderID, price); }}
MyEventHandler.java
import com.lmax.disruptor.EventHandler;public class MyEventHandler implements EventHandler<LogEvent> {private int tag;public MyEventHandler(int tag) {this.tag = tag;}@Overridepublic void onEvent(LogEvent event, long sequence, boolean endofBatch) throws Exception {// TODO Auto-generated method stubSystem.out.println("onEvent " + sequence + " tag " + this.tag + " threadID " + Thread.currentThread().getId() + " " + endofBatch);}}
MyEventTranslatorOneArg.java
import com.lmax.disruptor.EventTranslatorOneArg;public class MyEventTranslatorOneArg implements EventTranslatorOneArg<LogEvent, MyData> {@Overridepublic void translateTo(LogEvent event, long sequence, MyData data) {System.out.println(" assit publish event sequence " + sequence + " threadID " + Thread.currentThread().getId());event.setValue(data);}}
MyFactory.java
import com.lmax.disruptor.EventFactory;public class MyFactory implements EventFactory<LogEvent> {@Overridepublic LogEvent newInstance() {// TODO Auto-generated method stubreturn new LogEvent();}}
- Java 线程间通讯库 Disruptor
- java ----线程间通讯
- java线程间通讯
- Java 线程间通讯
- JAVA线程间通讯
- JAVA中管道通讯(线程间通讯)例子
- JAVA 多线程 线程间的通讯
- Java里快如闪电的线程间通讯
- Java里快如闪电的线程间通讯
- Java里快如闪电的线程间通讯
- Java里快如闪电的线程间通讯
- Java里快如闪电的线程间通讯
- JAVA 多线程 线程间的通讯
- Java中快如闪电的线程间通讯
- java线程通讯
- 【Java】线程管道通讯
- JAVA线程的通讯
- java线程之间通讯
- 移动硬盘无法访问位置不可用,里面的资料怎样找到
- 分解90=2*3*3*5*1
- oracle之 获取建表ddl语句
- 【笔记】二维数组中的查找
- mongodb复制集的实现
- Java 线程间通讯库 Disruptor
- 用线性回归进行糖尿病预测
- swagger
- 转载的动态表白程序
- Spring MVC基础
- 《数字技术》连载16: 第2章 数字器件 第11节 JK 触发器
- linux 中如何将两个iso合成一个
- dp专题:编辑距离
- mongodb之索引学习