├── 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()
--------------------------------------------------------------------------------