使用Disruptor 遇到問題,eventHander可能讀不到事件
程式碼使用disruptor 3.2.1, 使用多生產者單消費者模式,目的是為把併發寫透過disruptor轉成單寫
剛開始沒問題, 執行一會後,publish event 後,evenHandler不會被呼叫了,不知是disruptor問題,還是我程式碼的問題,但我把disruptor 換成jdk的ArrayBlockingQueue,沒出現問題。定位了很久,沒找出原因,以下是程式碼,沒有多少,就兩個類,希望有disruptor 使用經驗的道友幫忙分析一下
啟動disruptor且釋出事件的類:
eventHandler 類:
我也看了一下disruptor 中 BatchEventProcessor 的 run方法原始碼
onEvent 不被執行有兩種可能
1. sequenceBarrier.waitFor(nextSequence); 一直在等待
2. nextSequence <= availableSequence 這個條件一直不被滿足
run方法原始碼:
剛開始沒問題, 執行一會後,publish event 後,evenHandler不會被呼叫了,不知是disruptor問題,還是我程式碼的問題,但我把disruptor 換成jdk的ArrayBlockingQueue,沒出現問題。定位了很久,沒找出原因,以下是程式碼,沒有多少,就兩個類,希望有disruptor 使用經驗的道友幫忙分析一下
啟動disruptor且釋出事件的類:
public class CommandDisruptorServiceImpl implements CommandHandleService { private static final EventTranslatorVararg<CommandEvent> TRANSLATOR = new EventTranslatorVararg<CommandEvent>() { @Override public void translateTo(CommandEvent event, long sequence, Object... args) { if (args.length >= 3) { event.setCommandExecutor((CommandExecutor) args[0]); event.setCommand((Command<?>) args[1]); event.setCommandResult((CommandResult) args[2]); } } }; private Logger log = Logger.getLogger(CommandDisruptorServiceImpl.class); private volatile Disruptor<CommandEvent> disruptor; private volatile boolean started = false; @Override public void start(int bufSize) { if (null == disruptor) { synchronized (this) { if (null == disruptor) { disruptor = new Disruptor<CommandEvent>(new CommandEventFactory(), bufSize, Executors.newCachedThreadPool(new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread s = Executors.defaultThreadFactory() .newThread(r); s.setName("command-handle-thread"); s.setDaemon(true); return s; } })); disruptor.handleEventsWith(new CommandEventHandler()); disruptor.start(); started = true; log.info("disruptor started!"); } } } } @Override public void stop() { if (disruptor != null) { disruptor.shutdown(); started = false; disruptor = null; log.info("disruptor stopted"); } } @Override public <T> T postCommandAndWaitResult(CommandExecutor next, Command<T> command) { final RingBuffer<CommandEvent> ringBuffer = disruptor.getRingBuffer(); final CommandResult commandResult = new CommandResult(); ringBuffer.publishEvent(TRANSLATOR, next, command, commandResult); log.info("Command pulish to ringbuffer! cursor:" + disruptor.getCursor()); return waitCommandResult(commandResult, 2000); } @SuppressWarnings("unchecked") private <T> T waitCommandResult(CommandResult commandResult, long timeOut) { synchronized (commandResult) { try { while (!commandResult.isCommandIsFinish()) { log.info("Command waiting for result!"); commandResult.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } } log.debug("commandResult:" + commandResult.getResult()); return (T) commandResult.getResult(); } @Override public boolean isStarted() { return started; } } <p class="indent"> |
eventHandler 類:
public class CommandEventHandler implements EventHandler<CommandEvent> { private Logger log = Logger.getLogger(CommandEventHandler.class); @Override public void onEvent(CommandEvent event, long sequence, boolean endOfBatch) throws Exception { log.info("enter commandHandler! sequence:" + sequence + " endOfBatch:" + endOfBatch); Command<?> command = event.getCommand(); CommandExecutor cmdInterceptor = event.getCommandExecutor(); final CommandResult commandResult = event.getCommandResult(); try { commandResult.setResult(cmdInterceptor.execute(command)); } finally { synchronized (commandResult) { commandResult.setCommandIsFinish(true); log.info("to notify wait command!"); commandResult.notify(); } } } } <p class="indent"> |
我也看了一下disruptor 中 BatchEventProcessor 的 run方法原始碼
onEvent 不被執行有兩種可能
1. sequenceBarrier.waitFor(nextSequence); 一直在等待
2. nextSequence <= availableSequence 這個條件一直不被滿足
run方法原始碼:
@Override /** * It is ok to have another thread rerun this method after a halt(). * * @throws IllegalStateException if this object instance is already running in a thread */ @Override public void run() { if (!running.compareAndSet(false, true)) { throw new IllegalStateException("Thread is already running"); } sequenceBarrier.clearAlert(); notifyStart(); T event = null; long nextSequence = sequence.get() + 1L; try { while (true) { try { /** * onEvent 不被執行有兩種可能 *1. sequenceBarrier.waitFor(nextSequence); 一直在等待 *2. nextSequence <= availableSequence 這個條件一直不被滿足 */ final long availableSequence = sequenceBarrier.waitFor(nextSequence); while (nextSequence <= availableSequence) { event = dataProvider.get(nextSequence); eventHandler.onEvent(event, nextSequence, nextSequence == availableSequence); nextSequence++; } sequence.set(availableSequence); } catch (final TimeoutException e) { notifyTimeout(sequence.get()); } catch (final AlertException ex) { if (!running.get()) { break; } } catch (final Throwable ex) { exceptionHandler.handleEventException(ex, nextSequence, event); sequence.set(nextSequence); nextSequence++; } } } finally { notifyShutdown(); running.set(false); } } <p class="indent"> |
[該貼被abaddoncoder於2015-05-25 19:10修改過]
[該貼被abaddoncoder於2015-05-25 19:15修改過]
[該貼被abaddoncoder於2015-05-25 19:19修改過]
[該貼被abaddoncoder於2015-05-25 19:21修改過]
相關文章
- 大資料面試可能遇到的問題大資料面試
- iOS CocoaPods 安裝可能遇到的問題iOS
- lombok編譯遇到“找不到符號的問題”Lombok編譯符號
- PHPer、Laravel 面試可能會遇到的問題及答案PHPLaravel面試
- 面試可能會遇到的各種問題講解面試
- 使用git遇到的問題Git
- ueditor使用遇到的問題
- Go mod 使用遇到的問題Go
- laravel使用中遇到的問題Laravel
- c++使用遇到的問題C++
- 關於MQTT 使用遇到問題MQQT
- 使用 redisson 時遇到的問題Redis
- ORACLE RAC TO RAC DG搭建過程中可能遇到的問題Oracle
- Linux 安裝mysql 5.7.21 可能遇到的問題歸類LinuxMySql
- 【ROS教程】安裝ROS全流程及可能遇到的問題ROS
- 使用laravels可能遇到的小小坑Laravel
- 【MySQL】使用innobackup 2.4遇到的問題MySql
- 使用javap -v 命令遇到的問題Java
- air在go的其他版本上執行可能遇到的問題AIGo
- Linux 下部署Django專案你可能會遇到的問題!LinuxDjango
- PHPer 面試可能會遇到的問題及答案 | 掘金技術徵文PHP面試
- 使用WireShark分析使用RedisTemplate取不到值的問題Redis
- Disruptor-原始碼解讀原始碼
- 關於Unity中的UGUI優化,你可能遇到這些問題UnityUGUI優化
- OpenTiny Vue 元件庫適配微前端可能遇到的4個問題Vue元件前端
- 使用CodeMirror外掛遇到的問題
- 使用git add 遇到的小問題Git
- Vue使用中遇到的程式碼問題Vue
- Linux ~ CentOS使用中遇到的問題LinuxCentOS
- 記錄使用Performance API遇到的問題ORMAPI
- CKEditor使用中遇到的問題解決
- Fragstas軟體使用中遇到的問題
- 解決在使用Amoeba遇到的問題
- MATLAB讀取圖片遇到長寬的問題Matlab
- Disruptor 使用簡介
- Python學習者可能存在的幾個問題,你遇到過嗎?Python
- C++以多型方式處理陣列可能會遇到的問題C++多型陣列
- 使用Spring Data Jpa遇到問題彙總Spring