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
主机名: 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