grizzly 简化NIO事件开发
IOStrategies
使用 NIO 時,我們問的本質(zhì)問題是,我們將如何處理發(fā)生在 NIO channel 上的特定 NIO 事件。
通常我們有兩個選項:處理當(dāng)前(選擇器)線程中的 NIO 事件或?qū)⑵鋫鬟f給工作線程進(jìn)行處理。
1. Worker-thread IOStrategy.
最有用的IOStrategy,其中選擇器線程(Selector thread)將NIO事件處理委托給工作線程(worker threads)。
[外鏈圖片轉(zhuǎn)存失敗(img-ZkSlPvoN-1569084348722)(./images/workerthread-strategy.png)]
該IOStrategy具有很好的可擴(kuò)展性和安全性。我們可以根據(jù)需要更改選擇器(selector)和工作(worker)線程池的大小,
并且不存在在特定NIO事件處理期間可能發(fā)生的某些問題會影響在同一選擇器上注冊的其他通道的風(fēng)險。
2. Same-thread IOStrategy.
可能是最有效的IOStrategy。
與 work-thread IOStrategy不同,same-IOStrategy處理當(dāng)前線程中的NIO事件,從而避免了昂貴的線程上下文切換。
由于我們可以調(diào)整選擇器線程池的大小,所以此IOStrategy仍具有很好的可伸縮性,但是它確實有缺點。需要注意的是,
通道NIO事件處理不會阻塞或執(zhí)行任何長時間的操作,因為它可能會阻塞對同一選擇器上發(fā)生的其他NIO事件的處理。
3. Dynamic IOStrategy.
如前所述,worker-thread 和 same-thread 策略具有明顯的優(yōu)缺點。
但是,如果策略可以根據(jù)當(dāng)前條件(負(fù)載 load,收集的統(tǒng)計信息 gathered statistics等)嘗試在運行時智能地交換它們,該怎么辦?
該 IOStrategy 可能會帶來很多好處,并可以更好地控制資源。但是,重要的是不要使條件評估邏輯過于復(fù)雜,
因為它的復(fù)雜性將使IOStrategy與以前的兩種策略相比效率低下。
4. Leader-follower IOStrategy.
Grizzly 2.3附帶的最后一個IOStrategy是跟隨者策略(leader-follower strategy):
該IOStrategy與 worker-thread IOStrategy相似,但不是將NIO事件處理傳遞給 worker thread,
而是把Selector對 selector-thread 的控制權(quán)傳給work-thread,將工作線程更改為選擇器線程,
并且實際的NIO事件處理在當(dāng)前線程中進(jìn)行。
Grizzly 2.3提供了通用接口org.glassfish.grizzly.IOStrategy:
package org.glassfish.grizzly;import org.glassfish.grizzly.strategies.WorkerThreadPoolConfigProducer;import java.io.IOException; import java.util.concurrent.Executor;/*** <tt>strategy</tt> is responsible for making decision how* {@link Runnable} task will be run: in current thread, worker thread.** <tt>strategy</tt> can make any other processing decisions.* * @author Alexey Stashok*/ public interface IOStrategy extends WorkerThreadPoolConfigProducer {/*** The {@link org.glassfish.grizzly.nio.SelectorRunner} will invoke this* method to allow the strategy implementation to decide how the* {@link IOEvent} will be handled.** @param connection the {@link Connection} upon which the provided* {@link IOEvent} occurred.* @param ioEvent the {@link IOEvent} that triggered execution of this* <code>strategy</code>** @return <tt>true</tt>, if this thread should keep processing IOEvents on* the current and other Connections, or <tt>false</tt> if this thread* should hand-off the farther IOEvent processing on any Connections,* which means IOStrategy is becoming responsible for continuing IOEvent* processing (possibly starting new thread, which will handle IOEvents).** @throws IOException if an error occurs processing the {@link IOEvent}.*/boolean executeIoEvent(Connection connection, IOEvent ioEvent)throws IOException;/*** The {@link org.glassfish.grizzly.nio.SelectorRunner} will invoke this* method to allow the strategy implementation to decide how the* {@link IOEvent} will be handled.** @param connection the {@link Connection} upon which the provided* {@link IOEvent} occurred.* @param ioEvent the {@link IOEvent} that triggered execution of this* <code>strategy</code>* @param isIoEventEnabled <tt>true</tt> if IOEvent is still enabled on the* {@link Connection}, or <tt>false</tt> if IOEvent was preliminary disabled* or IOEvent is being simulated.** @return <tt>true</tt>, if this thread should keep processing IOEvents on* the current and other Connections, or <tt>false</tt> if this thread* should hand-off the farther IOEvent processing on any Connections,* which means IOStrategy is becoming responsible for continuing IOEvent* processing (possibly starting new thread, which will handle IOEvents).** @throws IOException if an error occurs processing the {@link IOEvent}.*/boolean executeIoEvent(Connection connection, IOEvent ioEvent,boolean isIoEventEnabled) throws IOException;/*** Returns an {@link Executor} to be used to run given <tt>ioEvent</tt>* processing for the given <tt>connection</tt>. A <tt>null</tt> value will* be returned if the <tt>ioEvent</tt> should be executed in the kernel thread.* * @param connection* @param ioEvent* @return an {@link Executor} to be used to run given <tt>ioEvent</tt>* processing for the given <tt>connection</tt>*/Executor getThreadPoolFor(Connection connection, IOEvent ioEvent); }IOStrategy實現(xiàn)可以決定如何處理特定的NIO事件。
根據(jù)上面的列表,Grizzly 2.3具有四個預(yù)定義的IOStrategy實現(xiàn):
- org.glassfish.grizzly.strategies.WorkerThreadIOStrategy
- org.glassfish.grizzly.strategies.SameThreadIOStrategy
- org.glassfish.grizzly.strategies.SimpleDynamicThreadStrategy
- org.glassfish.grizzly.strategies.LeaderFollowerIOStrategy
這些策略是按傳輸分配的,因此可以使用 Transport’s get/setIOStrategy 方法獲取/設(shè)置 IOStrategy.
TCP 和 UDP transports 默認(rèn)使用 worker-thread IOStrategy.
總結(jié)
以上是生活随笔為你收集整理的grizzly 简化NIO事件开发的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Mdfs] lc77. 组合(组合类型
- 下一篇: 超详细!旗舰SoC RK3588参数介绍