Sha*_*ams 13 java spring spring-scheduled spring-boot
我使用Spring Framework Scheduled来安排我的工作使用cron每5分钟运行一次.但有时我的工作无限期地等待外部资源,我不能把超时放在那里.我不能fixedDelay像以前的过程一样进入等待无限模式,我必须每隔5分钟刷新一次数据.
所以我在Spring框架中寻找任何一个选项来在它成功运行Scheduled之后停止该进程/线程fixed-time.
我发现下面的设置初始化ThreadPoolExecutor为120秒keepAliveTime,我把它放在@Configuration课堂上.任何人都能告诉我这项工作是否符合我的预期.
@Bean(destroyMethod="shutdown")
public Executor taskExecutor() {
int coreThreads = 8;
int maxThreads = 20;
final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
coreThreads, maxThreads, 120L,
TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()
);
threadPoolExecutor.allowCoreThreadTimeOut(true);
return threadPoolExecutor;
}
Run Code Online (Sandbox Code Playgroud)
我不确定这会按预期工作.确实keepAlive用于IDLE线程,我不知道你的等待资源的线程是否处于IDLE状态.此外,只有当线程数大于核心时,除非您监视线程池,否则您无法确切知道它何时发生.
keepAliveTime - 当线程数大于核心时,这是多余空闲线程在终止之前等待新任务的最长时间.
你能做的是以下几点:
public class MyTask {
private final long timeout;
public MyTask(long timeout) {
this.timeout = timeout;
}
@Scheduled(cron = "")
public void cronTask() {
Future<Object> result = doSomething();
result.get(timeout, TimeUnit.MILLISECONDS);
}
@Async
Future<Object> doSomething() {
//what i should do
//get ressources etc...
}
}
Run Code Online (Sandbox Code Playgroud)
不要忘记添加@EnableAsync
通过实现Callable,也可以在没有@Async的情况下执行相同的操作.
编辑:请记住,它将等到超时,但运行任务的线程不会被中断.发生TimeoutException时,您需要调用Future.cancel.并在任务中检查isInterrupted()以停止处理.如果您正在调用api,请确保选中isInterrupted().
小智 7
allowCoreThreadTimeOut和timeout设置没有帮助导致它只允许工作线程在一段时间后无法工作(参见javadocs)
你说你的工作无限期地等待外部资源.我确定这是因为您(或您使用的某些第三方库)使用的套接字默认为超时无限.还要记住jvm在socket.connect/read上阻塞时忽略了Thread.interrupt().
因此,找出您的任务中使用的女巫套接字库(以及它是如何使用的)并更改它的默认超时设置.
例如:RestTemplate在Spring内部广泛使用(在休息客户端,春季社交,春季安全OAuth等).并且有ClientHttpRequestFactory实现来创建RestTemplate实例.默认情况下,spring使用SimpleClientHttpRequestFactory,它使用JDK套接字.默认情况下,所有超时都是无限的.
因此,找出你准确冻结的位置,阅读它的文档并正确配置它.
PS如果你没有足够的时间和"感觉幸运"尝试运行你的应用程序将jvm属性sun.net.client.defaultConnectTimeout和 sun.net.client.defaultReadTimeout设置为一些合理的值(有关更多详细信息,请参阅文档)
| 归档时间: |
|
| 查看次数: |
7142 次 |
| 最近记录: |