Closed ruanzhi closed 4 years ago
我理解直接在在restore里面将holder里面所有的清理掉就OK了,为啥还需要恢复backup。 backup什么情况下才会有值呢?我理解如果是线程池中的线程,backup不可能有值存在。
backup什么情况下才会有值呢?
replay
操作的线程,与来源的capture
线程,是不同的。capture
的线程 在 业务中立的线程池 时,这样的线程 往往 也没有/不需要 有上下文。这2个前提成立时,backup
往往 不会有值。
当上面2点不成立时,如
CallerRunsPolicy
』,
则 提交到线程池的任务 在capture
线程直接执行,也就是 直接在业务线程中同步执行;ForkJoinPool
(包含并行执行Stream
与CompletableFuture
,底层使用ForkJoinPool
)的场景,展开的ForkJoinTask
会在调用线程中直接执行。这时 backup
是有值的,如果不做restore backup
业务线程里的上下文就丢了,
业务后续的执行就会有Bug
。 @ruanzhi
上面这个线程池场景,因为线程池的广泛大量使用, 是日常业务开发会碰到的问题(在线上,也解决过这样的问题)。
另外,如果用了像Reactive Programming
(RP
/反应式编程)这样的技术,
业务逻辑 完全是在Reactive
接管的 调度器(Scheduler
)/线程池 里执行的,
相应的问题出现的可能性就更高了。
『CallerRunsPolicy』情况理解,我再看看 反应式编程,非常感谢
@ruanzhi 好,有说的不清楚的,欢迎继续讨论 ♥️
这个Issue先Close了
提供反例式的回答
你说的是 map 是指
holder
吗?如果是,说明如下:『在capture 时清理map中的数据』 的问题
『在restore 清理map中的数据』 的问题
提交到线程池的任务 可能 在本线程直接执行(参见 『
CallerRunsPolicy
』。问题说明如下:
还是 因为 『提交到线程池的任务 可能 在本线程直接执行』『Restore』确保没有上面的
Bug
。按原则的回答
原则:通过 整体流程/设计/代码实现 来 分析/证明 正确性。 @soca2013
CRR(Capture/Replay/Restore)
是一个面向上下文传递设计的流程,通过这个流程的分析可以保证/证明 正确性。这个正确性的分析/证明 ,不依赖于 局部与反例。
总结一下:尽量首先去确定分析自己程序的正确性,而不是找反例。不分析而去依赖反例,又因为经验受限找不到反例认为没问题而上线,这其实就是我们程序出bug的原因。
@soca2013 有说得不明白的地方,欢迎交流。 ❤️
PS
如果你有兴趣『整体流程与分析』推荐:
TransmittableThreadLocal
的系统流程、查看代码实现。Originally posted by @oldratlee in https://github.com/alibaba/transmittable-thread-local/issues/145#issuecomment-517914234