• Java 并发框架Disruptor(七)


    Disruptor VS BlockingQueue的压测对比:

    import java.util.concurrent.ArrayBlockingQueue;
    
    public class ArrayBlockingQueue4Test {
    
        public static void main(String[] args) {
            final ArrayBlockingQueue<Data> queue = new ArrayBlockingQueue<Data>(100000000);
            final long startTime = System.currentTimeMillis();
            //向容器中添加元素
            new Thread(new Runnable() {
    
                public void run() {
                    long i = 0;
                    while (i < Constants.EVENT_NUM_OHM) {
                    	Data data = new Data(i, "c" + i);
                        try {
                            queue.put(data);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        i++;
                    }
                }
            }).start();
    
            new Thread(new Runnable() {
                public void run() {
                    int k = 0;
                    while (k < Constants.EVENT_NUM_OHM) {
                        try {
                            queue.take();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        k++;
                    }
                    long endTime = System.currentTimeMillis();
                    System.out.println("ArrayBlockingQueue costTime = " + (endTime - startTime) + "ms");
                }
            }).start();
        }
    }
    

      

    public interface Constants {
    
    	int EVENT_NUM_OHM = 1000000;
    	
    	int EVENT_NUM_FM = 50000000;
    	
    	int EVENT_NUM_OM = 10000000;
    	
    }
    

      

    import java.util.concurrent.Executors;
    
    import com.lmax.disruptor.BlockingWaitStrategy;
    import com.lmax.disruptor.BusySpinWaitStrategy;
    import com.lmax.disruptor.EventFactory;
    import com.lmax.disruptor.RingBuffer;
    import com.lmax.disruptor.YieldingWaitStrategy;
    import com.lmax.disruptor.dsl.Disruptor;
    import com.lmax.disruptor.dsl.ProducerType;
    
    public class DisruptorSingle4Test {
    
        public static void main(String[] args) {
            int ringBufferSize = 65536;
            final Disruptor<Data> disruptor = new Disruptor<Data>(
                     new EventFactory<Data>() {
    					public Data newInstance() {
    						return new Data();
    					}
    				},
                    ringBufferSize,
                    Executors.newSingleThreadExecutor(),
                    ProducerType.SINGLE, 
                    //new BlockingWaitStrategy()
                    new YieldingWaitStrategy()
            		);
    
            DataConsumer consumer = new DataConsumer();
            //消费数据
            disruptor.handleEventsWith(consumer);
            disruptor.start();
            new Thread(new Runnable() {
    
                public void run() {
                    RingBuffer<Data> ringBuffer = disruptor.getRingBuffer();
                    for (long i = 0; i < Constants.EVENT_NUM_OHM; i++) {
                        long seq = ringBuffer.next();
                        Data data = ringBuffer.get(seq);
                        data.setId(i);
                        data.setName("c" + i);
                        ringBuffer.publish(seq);
                    }
                }
            }).start();
        }
    }
    

      

    import com.lmax.disruptor.EventHandler;
    
    public class DataConsumer implements EventHandler<Data> {
    
        private long startTime;
        private int i;
    
        public DataConsumer() {
            this.startTime = System.currentTimeMillis();
        }
    
        public void onEvent(Data data, long seq, boolean bool)
                throws Exception {
            i++;
            if (i == Constants.EVENT_NUM_OHM) {
                long endTime = System.currentTimeMillis();
                System.out.println("Disruptor costTime = " + (endTime - startTime) + "ms");
            }
        }
    
    }
    

      

    import java.io.Serializable;
    
    public class Data implements Serializable {
    
    	private static final long serialVersionUID = 2035546038986494352L;
    	private Long id ;
    	private String name;
    	
    	public Data() {
    	}
    	public Data(Long id, String name) {
    		super();
    		this.id = id;
    		this.name = name;
    	}
    
    	public Long getId() {
    		return id;
    	}
    	public void setId(Long id) {
    		this.id = id;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    }
    

      

    BlockingQueue测试:

    1.建立一个工厂Event类,用于创建Event类实例对象

    2.需要有一个jian监听事件类,用于处理数据(Event类)

    3.实例化Disruptor实例,配置一系列参数,编写DisDisruptor核心组件

    4.编写生产者组件,向Disruptor容器中投递数据

    pom.xml添加:

    <dependency>
    	<groupId>com.lmax</groupId>
    	<artifactId>disruptor</artifactId>
    	<scope>3.3.2</scope>
    </dependency>
    

      

    public class OrderEvent {
    
    	private long value; //订单的价格
    
    	public long getValue() {
    		return value;
    	}
    
    	public void setValue(long value) {
    		this.value = value;
    	}
    }
    

      

    import com.lmax.disruptor.EventFactory;
    
    public class OrderEventFactory implements EventFactory<OrderEvent>{
    
    	public OrderEvent newInstance() {
    		return new OrderEvent();		//这个方法就是为了返回空的数据对象(Event)
    	}
    }
    

      

    public class OrderEventHandler implements EventHandler<OrderEvent>{
    
    	public void onEvent(OrderEvent event, long sequence, boolean endOfBatch) throws Exception {
    		Thread.sleep(Integer.MAX_VALUE);
    		System.err.println("消费者: " + event.getValue());
    	}
    }
    

      

    import java.nio.ByteBuffer;
    
    import com.lmax.disruptor.RingBuffer;
    
    public class OrderEventProducer {
    
    	private RingBuffer<OrderEvent> ringBuffer;
    	
    	public OrderEventProducer(RingBuffer<OrderEvent> ringBuffer) {
    		this.ringBuffer = ringBuffer;
    	}
    	
    	public void sendData(ByteBuffer data) {
    		//1 在生产者发送消息的时候, 首先 需要从我们的ringBuffer里面 获取一个可用的序号
    		long sequence = ringBuffer.next();	//0	
    		try {
    			//2 根据这个序号, 找到具体的 "OrderEvent" 元素 注意:此时获取的OrderEvent对象是一个没有被赋值的"空对象"
    			OrderEvent event = ringBuffer.get(sequence);
    			//3 进行实际的赋值处理
    			event.setValue(data.getLong(0));			
    		} finally {
    			//4 提交发布操作
    			ringBuffer.publish(sequence);			
    		}
    	}
    }
    

      

    import java.nio.ByteBuffer;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    import com.lmax.disruptor.BlockingWaitStrategy;
    import com.lmax.disruptor.RingBuffer;
    import com.lmax.disruptor.dsl.Disruptor;
    import com.lmax.disruptor.dsl.ProducerType;
    
    public class Main {
    	public static void main(String[] args) {
    		// 参数准备工作
    		OrderEventFactory orderEventFactory = new OrderEventFactory();
    		int ringBufferSize = 4;
    		ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
    		
    		/**
    		 * 1 eventFactory: 消息(event)工厂对象
    		 * 2 ringBufferSize: 容器的长度
    		 * 3 executor: 线程池(建议使用自定义线程池) RejectedExecutionHandler
    		 * 4 ProducerType: 单生产者 还是 多生产者
    		 * 5 waitStrategy: 等待策略
    		 */
    		//1. 实例化disruptor对象
    		Disruptor<OrderEvent> disruptor = new Disruptor<OrderEvent>(orderEventFactory,
    				ringBufferSize,
    				executor,
    				ProducerType.SINGLE,
    				new BlockingWaitStrategy());
    		
    		//2. 添加消费者的监听 (构建disruptor 与 消费者的一个关联关系)
    		disruptor.handleEventsWith(new OrderEventHandler());
    		
    		//3. 启动disruptor
    		disruptor.start();
    		
    		//4. 获取实际存储数据的容器: RingBuffer
    		RingBuffer<OrderEvent> ringBuffer = disruptor.getRingBuffer();
    		
    		OrderEventProducer producer = new OrderEventProducer(ringBuffer);
    		
    		ByteBuffer bb = ByteBuffer.allocate(8);
    		
    		for(long i = 0 ; i < 100; i ++){
    			bb.putLong(0, i);
    			producer.sendData(bb);
    		}
    		
    		disruptor.shutdown();
    		executor.shutdown();
    		
    	}
    }
    

      

     

     

    public final class BlockingWaitStrategy implements WaitStrategy
    {
        private final Lock lock = new ReentrantLock();
        private final Condition processorNotifyCondition = lock.newCondition();
    
        @Override
        public long waitFor(long sequence, Sequence cursorSequence, Sequence dependentSequence, SequenceBarrier barrier)
            throws AlertException, InterruptedException
        {
            long availableSequence;
            if ((availableSequence = cursorSequence.get()) < sequence)
            {
                lock.lock();
                try
                {
                    while ((availableSequence = cursorSequence.get()) < sequence)
                    {
                        barrier.checkAlert();
                        processorNotifyCondition.await();
                    }
                }
                finally
                {
                    lock.unlock();
                }
            }
    
            while ((availableSequence = dependentSequence.get()) < sequence)
            {
                barrier.checkAlert();
            }
    
            return availableSequence;
        }
    
        @Override
        public void signalAllWhenBlocking()
        {
            lock.lock();
            try
            {
                processorNotifyCondition.signalAll();
            }
            finally
            {
                lock.unlock();
            }
        }
    }
    

      

    public final class SleepingWaitStrategy implements WaitStrategy
    {
        private static final int DEFAULT_RETRIES = 200;
    
        private final int retries;
    
        public SleepingWaitStrategy()
        {
            this(DEFAULT_RETRIES);
        }
    
        public SleepingWaitStrategy(int retries)
        {
            this.retries = retries;
        }
    
        @Override
        public long waitFor(final long sequence, Sequence cursor, final Sequence dependentSequence, final SequenceBarrier barrier)
            throws AlertException, InterruptedException
        {
            long availableSequence;
            int counter = retries;
    
            while ((availableSequence = dependentSequence.get()) < sequence)
            {
                counter = applyWaitMethod(barrier, counter);
            }
    
            return availableSequence;
        }
    
        @Override
        public void signalAllWhenBlocking()
        {
        }
    
        private int applyWaitMethod(final SequenceBarrier barrier, int counter)
            throws AlertException
        {
            barrier.checkAlert();
    
            if (counter > 100)
            {
                --counter;
            }
            else if (counter > 0)
            {
                --counter;
                Thread.yield();
            }
            else
            {
                LockSupport.parkNanos(1L);
            }
    
            return counter;
        }
    }
    

      

    public final class YieldingWaitStrategy implements WaitStrategy
    {
        private static final int SPIN_TRIES = 100;
    
        @Override
        public long waitFor(final long sequence, Sequence cursor, final Sequence dependentSequence, final SequenceBarrier barrier)
            throws AlertException, InterruptedException
        {
            long availableSequence;
            int counter = SPIN_TRIES;
    
            while ((availableSequence = dependentSequence.get()) < sequence)
            {
                counter = applyWaitMethod(barrier, counter);
            }
    
            return availableSequence;
        }
    
        @Override
        public void signalAllWhenBlocking()
        {
        }
    
        private int applyWaitMethod(final SequenceBarrier barrier, int counter)
            throws AlertException
        {
            barrier.checkAlert();
    
            if (0 == counter)
            {
                Thread.yield();
            }
            else
            {
                --counter;
            }
    
            return counter;
        }
    }
    

      

     

  • 相关阅读:
    【BZOJ2127】happiness 最小割
    【xsy2748】 fly 矩阵快速幂
    [BZOJ2758] [SCOI2012]Blinker的噩梦 扫描线+set
    【BZOJ2732】【HNOI2012】射箭 二分+半平面交
    【xsy1162】鬼计之夜 最短路+二进制拆分
    【xsy2111】 【CODECHEF】Chef and Churus 分块+树状数组
    【xsy1116】数学题 奥数题
    【CODECHEF】Children Trips 倍增
    【xsy1098】第k小 可持久化trie
    扩展中国剩余定理(扩展CRT)详解
  • 原文地址:https://www.cnblogs.com/sunliyuan/p/10872380.html
Copyright © 2020-2023  润新知