标签:使用 complete lse event ble object notifyall pre 情况下
-- [I]java.util.concurrent.Future<V>
---- [I]io.netty.util.concurrent.Future<V>
------ [AC]AbstractFuture, [I]ChannelFuture, [I]Promise
-- [AC]AbstractFuture, [I]Promise -- [I]ChannelFuture, [I]Promise
---- DefaultPromise ---- [I]ChannelPromise
-- [I]ChannelPromise, [I]FlushCheckpoint, [C]DefaultPromise
---- [C]DefaultChannelPromise
整体定位是一个支持可写的Future,可以理解成:可以通过API设置结果的成功还是失败。对应netty的Future的特性1。
注意: 是否可以取消,是否成功等,在DefaultPromise实现中,是用一个result字段来实现的。并且用AtomicReferenceFieldUpdater结合volatile来完成在并发情况下字段的正确设置值。
完成get的实现逻辑,或者说定义的行为顺序,包含超时的get与一直等的get
+-----------+
| await |
+-----+-----+
|
|
+--------v-------+
| get cause |
+----+ cause == null +---+
| +----------------+ |
| |
| |
+------v------+ +------v------+
| throw exp | | getNow |
+-------------+ +-------------+
实现是线程安全的
await逻辑
+----------------+
+----Y-----+ isDone |
+----v---+ +----------------+
| return | N
+------+-+ |
^ +-------v--------+
+----Y---+ interrupted |
+----------------+
N
|
+----------+ +-------v--------+
| throw exp<--Y---+ checkDeadLock |
+----------+ +----------------+
N
+---------synchronized----------+
| |
| |
+-------v--------+ |
while-loop-+ !isDone +-----------+ |
| +----------------+ +-------v------+ |
| | incWaiters | |
| +-------+------+ |
| +----------------+ | |
| | wait <-----------+ |
| +-------+--------+ |
| | +--------------+ |
| +------------> decWaiters | |
| +--------------+ |
+-------------------------------------------+ |
|
+-------------------------------+
如果有其他人做了notify 但是此时任务还没有done,那么则会继续wait,因为这是一个while loop!
触发监听器逻辑有栈深度保护策略
前提是在同一个线程上,如果不是同一个线程就没有意义了。所以要判断executor.inEventLoop()。
在UnpaddedInternalThreadLocalMap中有个字段int futureListenerStackDepth字段来维护FutureListener的栈深度。
在同一个线程上,做notifyListener0之前会将futureListenerStackDepth加1,做完之后恢复原值。
这样如果在同一个线程递归调用到notifyListener0即notifyListener则会触发触发监听器逻辑有栈深度保护策略。
栈深度保护阈值默认是8,可以通过io.netty.defaultPromise.maxListenerStackDepth系统参数配置。
关于Promise的监听器
监听器是用listeners字段,这个字段是Object类型,竟然没有给一个明确的类型。在逻辑实现中有DefaultFutureListeners、GenericProgressiveFutureListener与GenericFutureListener等。
里面包了一个GenericFutureListener数组,达成一个复合的(列表型的)Listener。
GenericProgressiveFutureListener在netty自身里面没有用到具体实现。
安全执行任务的包装
private static void safeExecute(EventExecutor executor, Runnable task) {
try {
executor.execute(task);
} catch (Throwable t) {
rejectedExecutionLogger.error("Failed to submit a listener notification task. Event loop shut down?", t);
}
}
注意: rejectedExecutionLogger 单独的日志名称,所以可以单独配置。
[netty4][netty-common]Future与Promise分析
标签:使用 complete lse event ble object notifyall pre 情况下
原文地址:https://www.cnblogs.com/simoncook/p/10924578.html