java实现失败重试多次_Java执行任务有多次重试和超时

我认为,但我认为,如果您正在安排与网络相关的任务,则不应重试,而应最终并行运行.我稍后会描述其他方法.

关于您的代码,您应该将任务传递给执行程序,或将FutureTask传递给线程.它不会产生一个线程或自己执行.如果你有一个执行者(参见ExecutorService),你甚至不需要FutureTask,你可以简单地安排它并获得一个可调用的.

因此,假设您有ExecutorService,您可以调用:

Future future = yourExecutor.submit(task);

Future.get(timeout)将等待该超时并最终返回TimeoutException,即使该任务从未启动过,例如,如果Executor已经忙于完成其他工作而无法找到一个空闲线程.所以,你最终可能会尝试5次并等待几秒钟,而不会让任务有机会运行.这可能是也可能不是你所期望的,但通常不是.也许你应该等到它开始才能超时.

此外,您应该显式取消Future,即使它抛出TimeoutException,否则它可能会继续运行,因为文档和代码都没有说当get with timeout失败时它会停止.

即使你取消它,除非Callable被“正确写入”,它可能会继续运行一段时间.在这部分代码中你无法做到这一点,只要记住,没有任何线程可以“真正地停止”另一个线程在Java中所做的事情,并且有充分的理由.

但是,我认为您的任务主要与网络相关,因此它应该对线程中断做出正确的反应.

我通常使用不同的策略是这样的情况:

>我会写公共静态T执行(可调用任务,int maxTries,int超时),所以任务,最大尝试次数(可能是1),最大总超时(“我希望答案最多10秒,无论多少你尝试的次数,10秒或什么都不是“)

>我开始产生任务,将它交给执行者,然后调用future.get(timeout / tries)

>如果我收到结果,请将其退回.如果我收到异常,会再试一次(见后)

>但是如果我得到超时,我不会取消将来,而是将其保存在列表中.

>我检查是否已经过了太多时间,或者重试次数太多.在这种情况下,我取消列表中的所有期货并抛出异常,返回null,无论如何

>否则,我循环,再次安排任务(与第一个任务并行).

>见第2点

>如果我没有收到结果,我会检查列表中的未来,也许是之前生成的任务之一.

假设您的任务可以执行多次(因为我认为它们是,否则无法重试),对于网络内容我发现此解决方案可以更好地工作.

假设您的网络实际上非常繁忙,您要求网络连接,每次重试20秒.由于您的网络正忙,20次重试中没有一次能够在2秒内完成连接.但是,持续40秒的单次执行可能会设法连接和接收数据.这就像一个人在网络缓慢的情况下强制性地在页面上按f5,它不会有任何好处,因为每次浏览器都必须从头开始.

相反,我保持各种期货运行,第一个设法获取数据将返回结果,其他将停止.如果第一个挂起,第二个可以工作,或者第三个可能.

与浏览器相比,就像打开另一个选项卡并重试在那里加载页面而不关闭第一个选项卡.如果网络很慢,第二个将花费一些时间,但不会停止第一个,最终将正确加载.如果相反第一个标签挂起,第二个标签将快速加载.无论哪个先加载,我们都可以关闭另一个标签.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值