disruptor 效率相当高。当然使用的中 重要的是要注意场景了,因为ringbuffer的生产者获取可用的标记和消费者轮询消息的策略有很大影响。这里我只是简单的测试了一下loop 600万次200~300ms,6000万次 2.5s。使用的版本2.10.4
代码如下:
package disruptor;
import com.dc.gameserver.extComponents.Kit.util.random.Rnd;
import com.lmax.disruptor.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executors;
/**
* @author 石头哥哥
* </P>
* Date: 2014/11/28
* </P>
* Time: 20:10
* </P>
* Package: dcServer-parent
* </P>
* <p/>
* 注解:
*/
/**
* 自定义封装 事件
*/
class IntEvent {
private int value = -1;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public String toString() {
return String.valueOf(value);
}
private int values;
}
/**
* 消息封装
*/
class MessageEvent {
private byte[] bytes;//存储数据类
private int length;//数据长度
private int ID;//消息编号
public byte[] getBytes() {
return bytes;
}
public void setBytes(byte[] bytes) {
this.bytes = bytes;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public MessageEvent() {
}
public void build() {
}
}
//消费者
class IntEventProcessor implements WorkHandler<IntEvent> {
/**
* 数据分发处理
*
* @param event
* @throws Exception
*/
public void onEvent(IntEvent event) throws Exception {
// System.out.println("消费者 >>:" + event.getValue());
System.out.println("消费者>>:" + event.getName());
}
}
public class DisruptorTest {
public static void main(String[] args) throws InterruptedException {
//创建一个RingBuffer对象
/**
* Construct a RingBuffer with the full option set.
*
* @param eventFactory to newInstance entries for filling the RingBuffer 组装数据
* @param claimStrategy threading strategy for publisher claiming entries in the ring. 生产者通过ClaimStrategy 来申请下一个可用节点
* @param waitStrategy waiting strategy employed by processorsToTrack waiting on entries becoming available. 费者的等待策略(WARN)
*
* @throws IllegalArgumentException if bufferSize is not a power of 2
*/
RingBuffer<IntEvent> ringBuffer = new RingBuffer<IntEvent>(new EventFactory<IntEvent>() {
@Override
public IntEvent newInstance() {
IntEvent intEvent = new IntEvent();
int id = Rnd.getInt(0, 100);
intEvent.setName("xxx" + id);
intEvent.setValue(id);
return intEvent;
}
},
new MultiThreadedLowContentionClaimStrategy(1024), //sequences strategy
new BusySpinWaitStrategy()); // processor strategy-- 多核
/**
* 消费者初始化
*/
// SequenceBarrier对象指明了消费者可以消费的元素序号,
// 如果消费者的游标大于这个序号,那么消费者必须以WaitStrategy定义的策略等待。
SequenceBarrier sequenceBarrier = ringBuffer.newBarrier();
IntEventProcessor processors = new IntEventProcessor();
WorkerPool<IntEvent> applier = new WorkerPool<IntEvent>(
ringBuffer
, sequenceBarrier
, new IntEventExceptionHandler()
, processors);
/**
* gatingSequences的作用是防止生产者覆盖还未被消费者消费的元素
*/
List<Sequence> gatingSequences = new ArrayList<Sequence>();
Collections.addAll(gatingSequences, applier.getWorkerSequences());
ringBuffer.setGatingSequences(gatingSequences.toArray(new Sequence[gatingSequences.size()]));
/**
* 消费者处理线程
*/
applier.start(Executors.newCachedThreadPool());
/**
* 模拟产生数据 ,-- 生产者
* 测试 6000 千万次loop
*/
int count = 60000000;
long begin = System.currentTimeMillis();
for (int i = 0; i != count; ++i) {
/**
* Claim the next event in sequence
* 组装数据 ok ,通知消费线程 消费数据
*/
long next = ringBuffer.next();
// Get the event for a given sequence in the RingBuffer.
try {
IntEvent intEvent = ringBuffer.get(next);
/**
* 构建数据
* set set
* build
*/
} finally {
ringBuffer.publish(next);//
}
}
System.out.println("6000 千万次 loop ,end time:" + (System.currentTimeMillis() - begin) + "ms");
System.exit(0);
}
}
class IntEventExceptionHandler implements ExceptionHandler {
public void handleEventException(Throwable ex, long sequence, Object event) {
}
public void handleOnStartException(Throwable ex) {
}
public void handleOnShutdownException(Throwable ex) {
}
}
欢迎有使用jms经验的同学一起讨论 交流。qq:502959937