高併發框架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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章