我有一个用例,其中我的struts操作从文件系统读取文件,然后在服务器响应中将其返回。我想在重试逻辑中添加请求重试逻辑,然后再尝试读取文件,实现此目的的最佳方法是什么?
我希望在每次重试之间等待1秒后重试10次。我发现Thread.sleep(1000)将当前线程置于睡眠状态。这是正确的方法吗?
public String execute()
{
for(int i = 0; i < 10; i++) {
// Read the file system
if (break_condition) {
break;
}
Thread.sleep(1000);
}
}
有没有更好的方法来实现这一目标?
答案 0 :(得分:1)
最好不要在服务器上下文中使用Thread.sleep
,因为它可能会带来不必要的影响。
根据可用的服务器和框架,建议的方法将有所不同。但是,这种想法的核心是,您使用特定的API来计划或在服务器将来提供(重试)某些事情,并避免使用Thread.sleep()
。
主要区别在于线程在继续进行操作之前不会进入睡眠状态并保持空闲状态。该线程将在特定的持续时间后通知服务器做某事,然后该线程将继续工作。
如果您在Java-EE环境中,那么TimerService是个好主意。可以使用TimerService.createSingleActionTimer()
来实现。
例如,如果您在Jave EE服务器中,则可以执行以下操作:
import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Timer;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.TimerConfig;
@Stateless
public class RetryWithWaitBean {
@Resource
private SessionContext context;
/**
*Create a timer that will be activated after the duration passes.
*/
public void doActionAfterDuration(long durationMillis) {
final TimerConfig timerConfig= new TimerConfig()
timerConfig.setPersistent(false);
context.getTimerService()..createSingleActionTimer(durationMillis,timerConfig);
}
/** Automatically executed by server on timer expiration.
*/
@Timeout
public void timeout(Timer timer) {
System.out.println("Trying after timeout. Timer: " + timer.getInfo());
//Do custom action
doAction();
timer.cancel();
}
/**
* Doing the required action
*/
private void doAction(){
//add your logic here. This code will run after your timer.
System.out.println("Action DONE!");
}
}
然后您可以像这样使用它:
//This code should be in a managed context so that the server injects it.
@EJB
private RetryWithWaitBean retryWithWaitBean ;
然后您可以像这样使用它。
//do an action after 3000 milliseconds
retryWithWaitBean.doActionAfterDuration(3000);
根据您使用的框架,有很多方法可以达到相似的结果。