我在我的应用程序中使用spring ThreadPoolTaskExecutor。我的方法之一只需要在周五午夜才能被调用。在服务器启动时调用该方法。因此,我使用Thread.sleep()的方式如下
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未能找到我们想要尝试的执行程序的确切问题。
发布于 2016-11-15 13:37:56
您可以使用ScheduledExecutorService来安排在一定时间之后进行的工作。
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.schedule(() -> {
/*
* define work to be done inside this lambda
*/
}, diffTime, TimeUnit.MILLISECONDS);注意:如果希望工作在每个星期五午夜(因此不仅仅是下星期五)进行,您可以修改schedule命令,使其在指定的时间间隔内进行:
scheduler.scheduleAtFixedRate(() -> {
/*
* define work to be done inside this lambda
*/
}, diffTime, Duration.ofDays(7).toMillis(), TimeUnit.MILLISECONDS);发布于 2016-11-15 13:20:29
你在评论中说你在使用Spring。所以你可以用个cron表达式。有关如何使用Scheduler的详细信息,请参阅34.任务执行和调度。
@Scheduled(cron="0 0 1 ? * FRI *")
public void doSomething() {
// do stuff
}这将使它在星期五凌晨1点每周运行一次。您可以使用Cron制造者生成表达式。
在您的配置类中,您必须通过。
@Configuration
@EnableAsync
@EnableScheduling
public class AppConfig {
}发布于 2016-11-15 13:56:24
使用ScheduledExecutorService
private static final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);--如果你不担心精确性,(比如照顾夏令轮班):
您可以近似于固定的周期:
7* 24 * 60 * 60 * 1000 = 604800000 (每周以毫秒计)
然后你可以像这样打电话给遗嘱执行人:
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);这将导致执行者首先等待扩散延迟,然后以指定的周期执行任务。
如果你是担心的是精确性:然后打电话:
executor.schedule(task, difftime, TimeUnit.MILLISECONDS);只执行一次任务。在您的任务-调用一个方法,它将重新调度任务的下一个执行与新计算的差异时间。
https://stackoverflow.com/questions/40610624
复制相似问题