首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java中Thread.sleep()的替代方案

java中Thread.sleep()的替代方案
EN

Stack Overflow用户
提问于 2016-11-15 13:08:33
回答 4查看 8.9K关注 0票数 2

我在我的应用程序中使用spring ThreadPoolTaskExecutor。我的方法之一只需要在周五午夜才能被调用。在服务器启动时调用该方法。因此,我使用Thread.sleep()的方式如下

代码语言:javascript
复制
Calendar today = Calendar.getInstance();
int dayOfWeek = today.get(Calendar.DAY_OF_WEEK);
int daysUntilNextFriday = Calendar.FRIDAY - dayOfWeek;
if(daysUntilNextFriday < 0){
    daysUntilNextFriday = daysUntilNextFriday + 7;
}       

Calendar c = Calendar.getInstance();

c.add(Calendar.DAY_OF_YEAR, daysUntilNextFriday);
c.set(Calendar.HOUR_OF_DAY, 0); 
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
Date d1 = c.getTime();

long diffTime = d1.getTime() - new Date().getTime();

Thread.sleep(diffTime);

在某些情况下,它也可能等待超过1天。是否有更好的方法代替使用Thread.sleep()。我在一些地方看到,使用Thread.sleep()可能会导致性能问题。在我的例子中,有没有其他方法可以提高性能呢?

最初使用ThreadPoolTaskExecutor调度了近50个服务。有些服务没有正常启动,.We未能找到我们想要尝试的执行程序的确切问题。

请参考这个Spring调度程序意外地停止并重新启动。

EN

回答 4

Stack Overflow用户

发布于 2016-11-15 13:37:56

您可以使用ScheduledExecutorService来安排在一定时间之后进行的工作。

代码语言:javascript
复制
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.schedule(() -> {
            /*
             * define work to be done inside this lambda
             */
        }, diffTime, TimeUnit.MILLISECONDS);

注意:如果希望工作在每个星期五午夜(因此不仅仅是下星期五)进行,您可以修改schedule命令,使其在指定的时间间隔内进行:

代码语言:javascript
复制
scheduler.scheduleAtFixedRate(() -> {
    /*
     * define work to be done inside this lambda
     */
    }, diffTime, Duration.ofDays(7).toMillis(), TimeUnit.MILLISECONDS);
票数 3
EN

Stack Overflow用户

发布于 2016-11-15 13:20:29

你在评论中说你在使用Spring。所以你可以用个cron表达式。有关如何使用Scheduler的详细信息,请参阅34.任务执行和调度

代码语言:javascript
复制
@Scheduled(cron="0 0 1 ? * FRI *")
public void doSomething() {
    // do stuff
}

这将使它在星期五凌晨1点每周运行一次。您可以使用Cron制造者生成表达式。

在您的配置类中,您必须通过。

代码语言:javascript
复制
@Configuration
@EnableAsync
@EnableScheduling
public class AppConfig {
}
票数 2
EN

Stack Overflow用户

发布于 2016-11-15 13:56:24

使用ScheduledExecutorService

代码语言:javascript
复制
private static final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

--如果你不担心精确性,(比如照顾夏令轮班):

您可以近似于固定的周期:

7* 24 * 60 * 60 * 1000 = 604800000 (每周以毫秒计)

然后你可以像这样打电话给遗嘱执行人:

代码语言:javascript
复制
Runnable task = <your task extending Runnable>    
long difftime = <time to next friday>;
long week = 7 * 24 * 60 * 60 * 1000;

executor.scheduleAtFixedRate(task, difftime, week, TimeUnit.MILLISECONDS);

这将导致执行者首先等待扩散延迟,然后以指定的周期执行任务。

如果你是担心的是精确性:然后打电话:

代码语言:javascript
复制
executor.schedule(task, difftime, TimeUnit.MILLISECONDS);

只执行一次任务。在您的任务-调用一个方法,它将重新调度任务的下一个执行与新计算的差异时间。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40610624

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档