gpt4 book ai didi

java - JVM 流 API 回滚

转载 作者:行者123 更新时间:2023-12-01 16:47:31 28 4
gpt4 key购买 nike

当我们向流 API 提供一些输入时,它会将其分为 block ,并且 JVM 创建多个线程来在该 block 上执行执行。

问题:-

如果我将一百万个条目 ArrayList 作为并行管道的输入,在 JVM 内部线程对 List 进行前半部分计算之后,就会发生异常。

JVM 将如何处理 ROll Back。

JVM真的回滚到原来的状态了吗?

最佳答案

不存在回滚这种情况,正常情况下没有必要。流操作是从源读取生成新结果。如果发生异常,则不会有新的结果,并且在处理过程中创建的任何临时对象最终都会被垃圾收集。

在完美的世界中,终端操作将等待所有子任务完成,然后再将异常转发给调用者,但是 currently, it doesn’t ,另见this Q&A 。但即使确实如此,子任务也会继续处理项目,直到达到工作负载结束或检测到操作已中止,而不是回滚之前的工作。

请注意文档 explicitly discourages from using functions with stateful behavior ,因为使用并行流时结果可能是不确定的或不正确的。即使没有异常(exception),并行流在执行短路操作时也可能会处理对最终结果没有贡献的元素。无论哪种情况,函数产生的副作用都无法回滚。

必须强调的是,这也适用于副作用的合法使用,即使用 peekforEach,其操作在特殊情况下不会被撤消。如果您对the intended purpose使用peek ,这不是问题,因为报告元素已被处理仍然是正确的,即使结果由于后续异常而被丢弃。如果这是您传递给 forEach 的操作的问题,因为您不希望它们在特殊情况下发生,则无法首先收集元素,例如通过 toArraycollect(toList()),并在流操作正常完成后对结果执行 forEach

当然,如果操作仅修改具有自己的回滚机制的状态(例如将每个元素发送到数据库),则没有必要。

在某些情况下,流读取操作确实会修改源的状态,例如当 reading numbers from a random number generator , lines from a BufferedReader ,或tokens from a Scanner(Java 9) 。在这些情况下,操作还会对源产生无法撤消的影响。

对于 BufferedReader.lines()Scanner.tokens(),文档明确指出读取器/扫描器在操作后处于未指定状态,即使在非异常(exception)的情况下,随机数生成器通常也被视为生成不可预测的数字。因此,对于这些情况,没有回滚不会导致问题。

关于java - JVM 流 API 回滚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47201189/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com