├── MaShiBingDisruptor.iml ├── .idea ├── vcs.xml ├── misc.xml └── compiler.xml ├── src └── main │ ├── java │ └── com │ │ └── mashibing │ │ └── disruptor │ │ ├── LongEventFactory.java │ │ ├── LongEvent.java │ │ ├── LongEventHandler.java │ │ ├── Main03.java │ │ ├── Main01.java │ │ ├── Main05_WaitStrategy.java │ │ ├── Main06_MultiConsumer.java │ │ ├── Main04_ProducerType.java │ │ ├── Main07_ExceptionHandler.java │ │ └── Main02.java │ └── Disruptor.md └── pom.xml /MaShiBingDisruptor.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/java/com/mashibing/disruptor/LongEventFactory.java: -------------------------------------------------------------------------------- 1 | package com.mashibing.disruptor; 2 | 3 | import com.lmax.disruptor.EventFactory; 4 | 5 | public class LongEventFactory implements EventFactory { 6 | 7 | @Override 8 | public LongEvent newInstance() { 9 | return new LongEvent(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/mashibing/disruptor/LongEvent.java: -------------------------------------------------------------------------------- 1 | package com.mashibing.disruptor; 2 | 3 | public class LongEvent 4 | { 5 | private long value; 6 | 7 | public void set(long value) 8 | { 9 | this.value = value; 10 | } 11 | 12 | @Override 13 | public String toString() { 14 | return "LongEvent{" + 15 | "value=" + value + 16 | '}'; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/java/com/mashibing/disruptor/LongEventHandler.java: -------------------------------------------------------------------------------- 1 | package com.mashibing.disruptor; 2 | 3 | import com.lmax.disruptor.EventHandler; 4 | 5 | public class LongEventHandler implements EventHandler { 6 | 7 | /** 8 | * 9 | * @param event 10 | * @param sequence RingBuffer的序号 11 | * @param endOfBatch 是否为最后一个元素 12 | * @throws Exception 13 | */ 14 | 15 | public static long count = 0; 16 | 17 | @Override 18 | public void onEvent(LongEvent event, long sequence, boolean endOfBatch) throws Exception { 19 | count ++; 20 | System.out.println("[" + Thread.currentThread().getName() + "]" + event + " 序号:" + sequence); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | mashibing.com 8 | MaShiBing-Disruptor 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 1.8 13 | 1.8 14 | 15 | 16 | 17 | 18 | 19 | 20 | com.lmax 21 | disruptor 22 | 3.3.6 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/main/java/com/mashibing/disruptor/Main03.java: -------------------------------------------------------------------------------- 1 | package com.mashibing.disruptor; 2 | 3 | import com.lmax.disruptor.RingBuffer; 4 | import com.lmax.disruptor.dsl.Disruptor; 5 | import com.lmax.disruptor.util.DaemonThreadFactory; 6 | 7 | public class Main03 8 | { 9 | public static void main(String[] args) throws Exception 10 | { 11 | // Specify the size of the ring buffer, must be power of 2. 12 | int bufferSize = 1024; 13 | 14 | // Construct the Disruptor 15 | Disruptor disruptor = new Disruptor<>(LongEvent::new, bufferSize, DaemonThreadFactory.INSTANCE); 16 | 17 | // Connect the handler 18 | disruptor.handleEventsWith((event, sequence, endOfBatch) -> System.out.println("Event: " + event)); 19 | 20 | // Start the Disruptor, starts all threads running 21 | disruptor.start(); 22 | 23 | // Get the ring buffer from the Disruptor to be used for publishing. 24 | RingBuffer ringBuffer = disruptor.getRingBuffer(); 25 | 26 | 27 | //ringBuffer.publishEvent((event, sequence) -> event.set(10000L)); 28 | ringBuffer.publishEvent((event, sequence, l) -> event.set(l), 10000L); 29 | ringBuffer.publishEvent((event, sequence, l1, l2) -> event.set(l1 + l2), 30 | 10000L, 10000L); 31 | 32 | System.in.read(); 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/com/mashibing/disruptor/Main01.java: -------------------------------------------------------------------------------- 1 | package com.mashibing.disruptor; 2 | 3 | import java.util.concurrent.Executor; 4 | import java.util.concurrent.Executors; 5 | 6 | import com.lmax.disruptor.dsl.Disruptor; 7 | import com.lmax.disruptor.RingBuffer; 8 | import com.lmax.disruptor.util.DaemonThreadFactory; 9 | import java.nio.ByteBuffer; 10 | 11 | public class Main01 12 | { 13 | public static void main(String[] args) throws Exception 14 | { 15 | // The factory for the event 16 | LongEventFactory factory = new LongEventFactory(); 17 | 18 | // Specify the size of the ring buffer, must be power of 2. 19 | int bufferSize = 1024; 20 | 21 | // Construct the Disruptor 22 | Disruptor disruptor = new Disruptor<>(factory, bufferSize, Executors.defaultThreadFactory()); 23 | 24 | // Connect the handler 25 | disruptor.handleEventsWith(new LongEventHandler()); 26 | 27 | // Start the Disruptor, starts all threads running 28 | disruptor.start(); 29 | 30 | // Get the ring buffer from the Disruptor to be used for publishing. 31 | RingBuffer ringBuffer = disruptor.getRingBuffer(); 32 | 33 | //官方例程 34 | long sequence = ringBuffer.next(); // Grab the next sequence 35 | try 36 | { 37 | LongEvent event = ringBuffer.get(sequence); // Get the entry in the Disruptor 38 | // for the sequence 39 | event.set(8888L); // Fill with data 40 | } 41 | finally 42 | { 43 | ringBuffer.publish(sequence); 44 | } 45 | 46 | } 47 | } -------------------------------------------------------------------------------- /src/main/java/com/mashibing/disruptor/Main05_WaitStrategy.java: -------------------------------------------------------------------------------- 1 | package com.mashibing.disruptor; 2 | 3 | import com.lmax.disruptor.BlockingWaitStrategy; 4 | import com.lmax.disruptor.RingBuffer; 5 | import com.lmax.disruptor.SleepingWaitStrategy; 6 | import com.lmax.disruptor.dsl.Disruptor; 7 | import com.lmax.disruptor.dsl.ProducerType; 8 | 9 | import java.util.concurrent.*; 10 | 11 | public class Main05_WaitStrategy 12 | { 13 | public static void main(String[] args) throws Exception 14 | { 15 | // The factory for the event 16 | LongEventFactory factory = new LongEventFactory(); 17 | 18 | // Specify the size of the ring buffer, must be power of 2. 19 | int bufferSize = 1024; 20 | 21 | // Construct the Disruptor 22 | Disruptor disruptor = new Disruptor<>(factory, bufferSize, Executors.defaultThreadFactory(), 23 | ProducerType.MULTI, new SleepingWaitStrategy()); 24 | 25 | // Connect the handler 26 | disruptor.handleEventsWith(new LongEventHandler()); 27 | 28 | // Start the Disruptor, starts all threads running 29 | disruptor.start(); 30 | 31 | // Get the ring buffer from the Disruptor to be used for publishing. 32 | RingBuffer ringBuffer = disruptor.getRingBuffer(); 33 | 34 | //================================================================================================ 35 | final int threadCount = 50; 36 | CyclicBarrier barrier = new CyclicBarrier(threadCount); 37 | ExecutorService service = Executors.newCachedThreadPool(); 38 | for (long i = 0; i < threadCount; i++) { 39 | final long threadNum = i; 40 | service.submit(()-> { 41 | System.out.printf("Thread %s ready to start!\n", threadNum ); 42 | try { 43 | barrier.await(); 44 | } catch (InterruptedException e) { 45 | e.printStackTrace(); 46 | } catch (BrokenBarrierException e) { 47 | e.printStackTrace(); 48 | } 49 | 50 | for (int j = 0; j < 100; j++) { 51 | ringBuffer.publishEvent((event, sequence) -> { 52 | event.set(threadNum); 53 | System.out.println("生产了 " + threadNum); 54 | }); 55 | } 56 | 57 | 58 | }); 59 | } 60 | 61 | service.shutdown(); 62 | //disruptor.shutdown(); 63 | TimeUnit.SECONDS.sleep(3); 64 | System.out.println(LongEventHandler.count); 65 | } 66 | 67 | } -------------------------------------------------------------------------------- /src/main/java/com/mashibing/disruptor/Main06_MultiConsumer.java: -------------------------------------------------------------------------------- 1 | package com.mashibing.disruptor; 2 | 3 | import com.lmax.disruptor.RingBuffer; 4 | import com.lmax.disruptor.SleepingWaitStrategy; 5 | import com.lmax.disruptor.dsl.Disruptor; 6 | import com.lmax.disruptor.dsl.ProducerType; 7 | 8 | import java.util.concurrent.*; 9 | 10 | public class Main06_MultiConsumer 11 | { 12 | public static void main(String[] args) throws Exception 13 | { 14 | // The factory for the event 15 | LongEventFactory factory = new LongEventFactory(); 16 | 17 | // Specify the size of the ring buffer, must be power of 2. 18 | int bufferSize = 1024; 19 | 20 | // Construct the Disruptor 21 | Disruptor disruptor = new Disruptor<>(factory, bufferSize, Executors.defaultThreadFactory(), 22 | ProducerType.MULTI, new SleepingWaitStrategy()); 23 | 24 | // Connect the handlers 25 | LongEventHandler h1 = new LongEventHandler(); 26 | LongEventHandler h2 = new LongEventHandler(); 27 | disruptor.handleEventsWith(h1, h2); 28 | 29 | // Start the Disruptor, starts all threads running 30 | disruptor.start(); 31 | 32 | // Get the ring buffer from the Disruptor to be used for publishing. 33 | RingBuffer ringBuffer = disruptor.getRingBuffer(); 34 | 35 | //================================================================================================ 36 | final int threadCount = 10; 37 | CyclicBarrier barrier = new CyclicBarrier(threadCount); 38 | ExecutorService service = Executors.newCachedThreadPool(); 39 | for (long i = 0; i < threadCount; i++) { 40 | final long threadNum = i; 41 | service.submit(()-> { 42 | System.out.printf("Thread %s ready to start!\n", threadNum ); 43 | try { 44 | barrier.await(); 45 | } catch (InterruptedException e) { 46 | e.printStackTrace(); 47 | } catch (BrokenBarrierException e) { 48 | e.printStackTrace(); 49 | } 50 | 51 | for (int j = 0; j < 10; j++) { 52 | ringBuffer.publishEvent((event, sequence) -> { 53 | event.set(threadNum); 54 | System.out.println("生产了 " + threadNum); 55 | }); 56 | } 57 | 58 | 59 | }); 60 | } 61 | 62 | service.shutdown(); 63 | //disruptor.shutdown(); 64 | TimeUnit.SECONDS.sleep(3); 65 | System.out.println(LongEventHandler.count); 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /src/main/java/com/mashibing/disruptor/Main04_ProducerType.java: -------------------------------------------------------------------------------- 1 | package com.mashibing.disruptor; 2 | 3 | import com.lmax.disruptor.BlockingWaitStrategy; 4 | import com.lmax.disruptor.RingBuffer; 5 | import com.lmax.disruptor.dsl.Disruptor; 6 | import com.lmax.disruptor.dsl.ProducerType; 7 | import com.lmax.disruptor.util.DaemonThreadFactory; 8 | 9 | import java.util.concurrent.*; 10 | 11 | public class Main04_ProducerType 12 | { 13 | public static void main(String[] args) throws Exception 14 | { 15 | // The factory for the event 16 | LongEventFactory factory = new LongEventFactory(); 17 | 18 | // Specify the size of the ring buffer, must be power of 2. 19 | int bufferSize = 1024; 20 | 21 | // Construct the Disruptor 22 | // Disruptor disruptor = new Disruptor<>(factory, bufferSize, Executors.defaultThreadFactory()); 23 | 24 | //指定单线程模式 25 | Disruptor disruptor = new Disruptor<>(factory, bufferSize, Executors.defaultThreadFactory(), 26 | ProducerType.MULTI, new BlockingWaitStrategy()); 27 | 28 | // Connect the handler 29 | disruptor.handleEventsWith(new LongEventHandler()); 30 | 31 | // Start the Disruptor, starts all threads running 32 | disruptor.start(); 33 | 34 | // Get the ring buffer from the Disruptor to be used for publishing. 35 | RingBuffer ringBuffer = disruptor.getRingBuffer(); 36 | 37 | //================================================================================================ 38 | final int threadCount = 50; 39 | CyclicBarrier barrier = new CyclicBarrier(threadCount); 40 | ExecutorService service = Executors.newCachedThreadPool(); 41 | for (long i = 0; i < threadCount; i++) { 42 | final long threadNum = i; 43 | service.submit(()-> { 44 | System.out.printf("Thread %s ready to start!\n", threadNum ); 45 | try { 46 | barrier.await(); 47 | } catch (InterruptedException e) { 48 | e.printStackTrace(); 49 | } catch (BrokenBarrierException e) { 50 | e.printStackTrace(); 51 | } 52 | 53 | for (int j = 0; j < 100; j++) { 54 | ringBuffer.publishEvent((event, sequence) -> { 55 | event.set(threadNum); 56 | System.out.println("生产了 " + threadNum); 57 | }); 58 | } 59 | 60 | 61 | }); 62 | } 63 | 64 | service.shutdown(); 65 | //disruptor.shutdown(); 66 | TimeUnit.SECONDS.sleep(3); 67 | System.out.println(LongEventHandler.count); 68 | } 69 | 70 | } -------------------------------------------------------------------------------- /src/main/java/com/mashibing/disruptor/Main07_ExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.mashibing.disruptor; 2 | 3 | import com.lmax.disruptor.EventHandler; 4 | import com.lmax.disruptor.ExceptionHandler; 5 | import com.lmax.disruptor.RingBuffer; 6 | import com.lmax.disruptor.SleepingWaitStrategy; 7 | import com.lmax.disruptor.dsl.Disruptor; 8 | import com.lmax.disruptor.dsl.ProducerType; 9 | 10 | import java.util.concurrent.*; 11 | 12 | public class Main07_ExceptionHandler 13 | { 14 | public static void main(String[] args) throws Exception 15 | { 16 | // The factory for the event 17 | LongEventFactory factory = new LongEventFactory(); 18 | 19 | // Specify the size of the ring buffer, must be power of 2. 20 | int bufferSize = 1024; 21 | 22 | // Construct the Disruptor 23 | Disruptor disruptor = new Disruptor<>(factory, bufferSize, Executors.defaultThreadFactory(), 24 | ProducerType.MULTI, new SleepingWaitStrategy()); 25 | 26 | // Connect the handlers 27 | EventHandler h1 = (event, sequence, end) -> { 28 | System.out.println(event); 29 | throw new Exception("消费者出异常"); 30 | }; 31 | disruptor.handleEventsWith(h1); 32 | 33 | disruptor.handleExceptionsFor(h1).with(new ExceptionHandler() { 34 | @Override 35 | public void handleEventException(Throwable throwable, long l, LongEvent longEvent) { 36 | throwable.printStackTrace(); 37 | } 38 | 39 | @Override 40 | public void handleOnStartException(Throwable throwable) { 41 | System.out.println("Exception Start to Handle!"); 42 | } 43 | 44 | @Override 45 | public void handleOnShutdownException(Throwable throwable) { 46 | System.out.println("Exception Handled!"); 47 | } 48 | }); 49 | 50 | // Start the Disruptor, starts all threads running 51 | disruptor.start(); 52 | 53 | // Get the ring buffer from the Disruptor to be used for publishing. 54 | RingBuffer ringBuffer = disruptor.getRingBuffer(); 55 | 56 | //================================================================================================ 57 | final int threadCount = 1; 58 | CyclicBarrier barrier = new CyclicBarrier(threadCount); 59 | ExecutorService service = Executors.newCachedThreadPool(); 60 | for (long i = 0; i < threadCount; i++) { 61 | final long threadNum = i; 62 | service.submit(()-> { 63 | System.out.printf("Thread %s ready to start!\n", threadNum ); 64 | try { 65 | barrier.await(); 66 | } catch (InterruptedException e) { 67 | e.printStackTrace(); 68 | } catch (BrokenBarrierException e) { 69 | e.printStackTrace(); 70 | } 71 | 72 | for (int j = 0; j < 1; j++) { 73 | ringBuffer.publishEvent((event, sequence) -> { 74 | event.set(threadNum); 75 | System.out.println("生产了 " + threadNum); 76 | }); 77 | } 78 | 79 | 80 | }); 81 | } 82 | 83 | service.shutdown(); 84 | //disruptor.shutdown(); 85 | TimeUnit.SECONDS.sleep(3); 86 | System.out.println(LongEventHandler.count); 87 | } 88 | 89 | } -------------------------------------------------------------------------------- /src/main/java/com/mashibing/disruptor/Main02.java: -------------------------------------------------------------------------------- 1 | package com.mashibing.disruptor; 2 | 3 | import com.lmax.disruptor.*; 4 | import com.lmax.disruptor.dsl.Disruptor; 5 | import com.lmax.disruptor.util.DaemonThreadFactory; 6 | 7 | public class Main02 8 | { 9 | public static void main(String[] args) throws Exception 10 | { 11 | // The factory for the event 12 | LongEventFactory factory = new LongEventFactory(); 13 | 14 | // Specify the size of the ring buffer, must be power of 2. 15 | int bufferSize = 1024; 16 | 17 | // Construct the Disruptor 18 | Disruptor disruptor = new Disruptor<>(factory, bufferSize, DaemonThreadFactory.INSTANCE); 19 | 20 | // Connect the handler 21 | disruptor.handleEventsWith(new LongEventHandler()); 22 | 23 | // Start the Disruptor, starts all threads running 24 | disruptor.start(); 25 | 26 | // Get the ring buffer from the Disruptor to be used for publishing. 27 | RingBuffer ringBuffer = disruptor.getRingBuffer(); 28 | 29 | //=============================================================== 为Java8的写法做准备 30 | EventTranslator translator1 = new EventTranslator() { 31 | @Override 32 | public void translateTo(LongEvent event, long sequence) { 33 | event.set(8888L); 34 | } 35 | }; 36 | 37 | ringBuffer.publishEvent(translator1); 38 | 39 | //=============================================================== 40 | EventTranslatorOneArg translator2 = new EventTranslatorOneArg() { 41 | @Override 42 | public void translateTo(LongEvent event, long sequence, Long l) { 43 | event.set(l); 44 | } 45 | }; 46 | 47 | ringBuffer.publishEvent(translator2, 7777L); 48 | 49 | //=============================================================== 50 | EventTranslatorTwoArg translator3 = new EventTranslatorTwoArg() { 51 | @Override 52 | public void translateTo(LongEvent event, long sequence, Long l1, Long l2) { 53 | event.set(l1 + l2); 54 | } 55 | }; 56 | 57 | ringBuffer.publishEvent(translator3, 10000L, 10000L); 58 | 59 | //=============================================================== 60 | EventTranslatorThreeArg translator4 = new EventTranslatorThreeArg() { 61 | @Override 62 | public void translateTo(LongEvent event, long sequence, Long l1, Long l2, Long l3) { 63 | event.set(l1 + l2 + l3); 64 | } 65 | }; 66 | 67 | ringBuffer.publishEvent(translator4, 10000L, 10000L, 1000L); 68 | 69 | //=============================================================== 70 | EventTranslatorVararg translator5 = new EventTranslatorVararg() { 71 | 72 | @Override 73 | public void translateTo(LongEvent event, long sequence, Object... objects) { 74 | long result = 0; 75 | for(Object o : objects) { 76 | long l = (Long)o; 77 | result += l; 78 | } 79 | event.set(result); 80 | } 81 | }; 82 | 83 | ringBuffer.publishEvent(translator5, 10000L, 10000L, 10000L, 10000L); 84 | 85 | } 86 | } -------------------------------------------------------------------------------- /src/main/Disruptor.md: -------------------------------------------------------------------------------- 1 | # Disruptor 2 | 3 | ## 介绍 4 | 5 | 主页:http://lmax-exchange.github.io/disruptor/ 6 | 7 | 源码:https://github.com/LMAX-Exchange/disruptor 8 | 9 | GettingStarted: https://github.com/LMAX-Exchange/disruptor/wiki/Getting-Started 10 | 11 | api: http://lmax-exchange.github.io/disruptor/docs/index.html 12 | 13 | maven: https://mvnrepository.com/artifact/com.lmax/disruptor 14 | 15 | ## Disruptor的特点 16 | 17 | 对比ConcurrentLinkedQueue : 链表实现 18 | 19 | JDK中没有ConcurrentArrayQueue 20 | 21 | Disruptor是数组实现的 22 | 23 | 无锁,高并发,使用环形Buffer,直接覆盖(不用清除)旧的数据,降低GC频率 24 | 25 | 实现了基于事件的生产者消费者模式(观察者模式) 26 | 27 | ## RingBuffer 28 | 29 | 环形队列 30 | 31 | RingBuffer的序号,指向下一个可用的元素 32 | 33 | 采用数组实现,没有首尾指针 34 | 35 | 对比ConcurrentLinkedQueue,用数组实现的速度更快 36 | 37 | > 假如长度为8,当添加到第12个元素的时候在哪个序号上呢?用12%8决定 38 | > 39 | > 当Buffer被填满的时候到底是覆盖还是等待,由Producer决定 40 | > 41 | > 长度设为2的n次幂,利于二进制计算,例如:12%8 = 12 & (8 - 1) pos = num & (size -1) 42 | 43 | ## Disruptor开发步骤 44 | 45 | 1. 定义Event - 队列中需要处理的元素 46 | 47 | 2. 定义Event工厂,用于填充队列 48 | 49 | > 这里牵扯到效率问题:disruptor初始化的时候,会调用Event工厂,对ringBuffer进行内存的提前分配 50 | > 51 | > GC产频率会降低 52 | 53 | 3. 定义EventHandler(消费者),处理容器中的元素 54 | 55 | ## 事件发布模板 56 | 57 | ```java 58 | long sequence = ringBuffer.next(); // Grab the next sequence 59 | try { 60 | LongEvent event = ringBuffer.get(sequence); // Get the entry in the Disruptor 61 | // for the sequence 62 | event.set(8888L); // Fill with data 63 | } finally { 64 | ringBuffer.publish(sequence); 65 | } 66 | ``` 67 | 68 | ## 使用EventTranslator发布事件 69 | 70 | ```java 71 | //=============================================================== 72 | EventTranslator translator1 = new EventTranslator() { 73 | @Override 74 | public void translateTo(LongEvent event, long sequence) { 75 | event.set(8888L); 76 | } 77 | }; 78 | 79 | ringBuffer.publishEvent(translator1); 80 | 81 | //=============================================================== 82 | EventTranslatorOneArg translator2 = new EventTranslatorOneArg() { 83 | @Override 84 | public void translateTo(LongEvent event, long sequence, Long l) { 85 | event.set(l); 86 | } 87 | }; 88 | 89 | ringBuffer.publishEvent(translator2, 7777L); 90 | 91 | //=============================================================== 92 | EventTranslatorTwoArg translator3 = new EventTranslatorTwoArg() { 93 | @Override 94 | public void translateTo(LongEvent event, long sequence, Long l1, Long l2) { 95 | event.set(l1 + l2); 96 | } 97 | }; 98 | 99 | ringBuffer.publishEvent(translator3, 10000L, 10000L); 100 | 101 | //=============================================================== 102 | EventTranslatorThreeArg translator4 = new EventTranslatorThreeArg() { 103 | @Override 104 | public void translateTo(LongEvent event, long sequence, Long l1, Long l2, Long l3) { 105 | event.set(l1 + l2 + l3); 106 | } 107 | }; 108 | 109 | ringBuffer.publishEvent(translator4, 10000L, 10000L, 1000L); 110 | 111 | //=============================================================== 112 | EventTranslatorVararg translator5 = new EventTranslatorVararg() { 113 | 114 | @Override 115 | public void translateTo(LongEvent event, long sequence, Object... objects) { 116 | long result = 0; 117 | for(Object o : objects) { 118 | long l = (Long)o; 119 | result += l; 120 | } 121 | event.set(result); 122 | } 123 | }; 124 | 125 | ringBuffer.publishEvent(translator5, 10000L, 10000L, 10000L, 10000L); 126 | ``` 127 | 128 | ## 使用Lamda表达式 129 | 130 | ```java 131 | package com.mashibing.disruptor; 132 | 133 | import com.lmax.disruptor.RingBuffer; 134 | import com.lmax.disruptor.dsl.Disruptor; 135 | import com.lmax.disruptor.util.DaemonThreadFactory; 136 | 137 | public class Main03 138 | { 139 | public static void main(String[] args) throws Exception 140 | { 141 | // Specify the size of the ring buffer, must be power of 2. 142 | int bufferSize = 1024; 143 | 144 | // Construct the Disruptor 145 | Disruptor disruptor = new Disruptor<>(LongEvent::new, bufferSize, DaemonThreadFactory.INSTANCE); 146 | 147 | // Connect the handler 148 | disruptor.handleEventsWith((event, sequence, endOfBatch) -> System.out.println("Event: " + event)); 149 | 150 | // Start the Disruptor, starts all threads running 151 | disruptor.start(); 152 | 153 | // Get the ring buffer from the Disruptor to be used for publishing. 154 | RingBuffer ringBuffer = disruptor.getRingBuffer(); 155 | 156 | 157 | ringBuffer.publishEvent((event, sequence) -> event.set(10000L)); 158 | 159 | System.in.read(); 160 | } 161 | } 162 | ``` 163 | 164 | ## ProducerType生产者线程模式 165 | 166 | > ProducerType有两种模式 Producer.MULTI和Producer.SINGLE 167 | > 168 | > 默认是MULTI,表示在多线程模式下产生sequence 169 | > 170 | > 如果确认是单线程生产者,那么可以指定SINGLE,效率会提升 171 | > 172 | > 如果是多个生产者(多线程),但模式指定为SINGLE,会出什么问题呢? 173 | 174 | ## 等待策略 175 | 176 | 1,(常用)BlockingWaitStrategy:通过线程阻塞的方式,等待生产者唤醒,被唤醒后,再循环检查依赖的sequence是否已经消费。 177 | 178 | 2,BusySpinWaitStrategy:线程一直自旋等待,可能比较耗cpu 179 | 180 | 3,LiteBlockingWaitStrategy:线程阻塞等待生产者唤醒,与BlockingWaitStrategy相比,区别在signalNeeded.getAndSet,如果两个线程同时访问一个访问waitfor,一个访问signalAll时,可以减少lock加锁次数. 181 | 182 | 4,LiteTimeoutBlockingWaitStrategy:与LiteBlockingWaitStrategy相比,设置了阻塞时间,超过时间后抛异常。 183 | 184 | 5,PhasedBackoffWaitStrategy:根据时间参数和传入的等待策略来决定使用哪种等待策略 185 | 186 | 6,TimeoutBlockingWaitStrategy:相对于BlockingWaitStrategy来说,设置了等待时间,超过后抛异常 187 | 188 | 7,(常用)YieldingWaitStrategy:尝试100次,然后Thread.yield()让出cpu 189 | 190 | 8. (常用)SleepingWaitStrategy : sleep 191 | 192 | ## 消费者异常处理 193 | 194 | 默认:disruptor.setDefaultExceptionHandler() 195 | 196 | 覆盖:disruptor.handleExceptionFor().with() --------------------------------------------------------------------------------