disruptor 测试

disruptor  效率相当高。当然使用的中 重要的是要注意场景了,因为ringbuffer的生产者获取可用的标记和消费者轮询消息的策略有很大影响。这里我只是简单的测试了一下loop 600万次200~300ms,6000万次 2.5s。使用的版本2.10.4

代码如下:disruptor 测试_第1张图片

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 

你可能感兴趣的:(队列,高性能,disruptor)