高并发框架disruptor简单测试

Java中并发无外乎多线程加锁等方式,平时用的比较多的就是util.concurrency下的一些工具。除此之外业界比较推崇的就是erlang、scala中较为流行的actor模型,该模型是著名的无锁模型,actor(可以简单认为是轻量线程)之间通过发送消息进行通信,由事件驱动,全程无锁。

最近看论坛发现了另外一个并发模型-disruptor。它比较特殊,其核心是ringbuffer,闲来无事做了个简单测试。用它来模拟典型的生产者-消费者问题,本例中一个消费者-一个生产者,并将disruptor和jdk提供的ArrayBlockingQueue做了对比,发现在本人的笔记本上前者比后者快将近10倍!

 

闲话少叙,直接贴代码,如有意见或问题欢迎拍砖。

 

public class BqTest {
	static boolean ft = true;
	static boolean z = true;
	/**
	 * <b>Title:</b> main</br>
	 * <b>Description:</b> 
	 * @param args void   
	 * @throws:
	 * @author: shenbaise
	 */
	public static void main(String[] args) {
		BqTest bt = new BqTest();
		bt.test();
	}
	
	
	public void test(){
		
		long cost = System.currentTimeMillis();
		final BlockingQueue<Long> bq = new ArrayBlockingQueue<Long>(4096);
		
		Runnable p = new Runnable() {
			public void run() {
				for(int i= 0;i<100000000;i++){
					try {
						bq.put((long) i);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				ft = false;
			}
		};
		
		Runnable c = new Runnable() {
			public void run() {
				while(ft || !bq.isEmpty()){
					try {
						bq.take();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				z = false;
			}
		};
		
		new Thread(c).start();
		
		new Thread(p).start();
		
		while(z){
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("cost:"+(System.currentTimeMillis() - cost));
	}
	
	
}

 

disruptor的测试稍微麻烦点。

public final class ValueEvent {
	private long value;

	public long getValue() {
		return value;
	}

	public void setValue(final long value) {
		this.value = value;
	}

	public final static EventFactory<ValueEvent> EVENT_FACTORY = new EventFactory<ValueEvent>() {
		public ValueEvent newInstance() {
			return new ValueEvent();
		}
	};
}

 

public class MyEventHandler implements EventHandler<ValueEvent>{

	public long count = 0;

	public void onEvent(ValueEvent arg0, long arg1, boolean arg2)
			throws Exception {
		arg0.getValue();
		//  为了公平这里什么都不做
	}
}

 

/**
 * @author shenbaise
 */
public class RbTest {
		
	private static final int BUFFER_SIZE = 4096;
	
	public static void main(String[] args) {
		RbTest test = new RbTest();
		test.test();
	}
	
	public void test() {
		long cost = System.currentTimeMillis();
		RingBuffer<ValueEvent> ringBuffer =
	        createSingleProducer(ValueEvent.EVENT_FACTORY, BUFFER_SIZE, 
	        		new YieldingWaitStrategy());
	    SequenceBarrier sequenceBarrier = ringBuffer.newBarrier();
	    MyEventHandler handler = new MyEventHandler();
	    BatchEventProcessor<ValueEvent> batchEventProcessor = 
	    	new BatchEventProcessor<ValueEvent>(ringBuffer, sequenceBarrier, handler);
	    ringBuffer.addGatingSequences(batchEventProcessor.getSequence());
	    ExecutorService executor = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory);
      executor.submit(batchEventProcessor);
	final RingBuffer<ValueEvent> rb = ringBuffer;
        for (long i = 0; i < 100000000; i++)
        {
            long next = rb.next();
            rb.get(next).setValue(i);
            rb.publish(next);
        }
        batchEventProcessor.halt();
        System.out.println("cost:"+(System.currentTimeMillis() - cost));
	}
}

 

最终ArrayBlockingQueue需要越20秒,而disruptor仅2秒左右。

测试环境:

写道
jdk7

主机名: WHITEME-PC
OS 名称: Microsoft Windows 7 旗舰版

系统制造商: LENOVO
系统型号: INVALID
系统类型: x64-based PC
处理器: 安装了 1 个处理器。
[01]: Intel64 Family 6 Model 37 Stepping 5 GenuineIntel ~2533 Mhz
BIOS 版本: LENOVO 2ECN29WW , 2010/9/21
物理内存总量: 3,957 MB
可用的物理内存: 987 MB
虚拟内存: 最大值: 7,911 MB
虚拟内存: 可用: 4,344 MB
虚拟内存: 使用中: 3,567 MB

 

你可能感兴趣的:(disruptor)