Java 在新线程中运行调度
我正在查询API以创建报告,并希望在5分钟后加载该报告。我想使用一个Java 在新线程中运行调度,java,multithreading,scheduledexecutorservice,Java,Multithreading,Scheduledexecutorservice,我正在查询API以创建报告,并希望在5分钟后加载该报告。我想使用一个ScheduledExecutorService。由于我不希望执行者阻止我的线程,我正在为此创建一个新线程,但我不确定这是否是正确的方法。这是我的密码: Thread thread = new Thread() { public void run() { log.info("Starting..."); new RequestReport().runSchedule
ScheduledExecutorService
。由于我不希望执行者阻止我的线程,我正在为此创建一个新线程,但我不确定这是否是正确的方法。这是我的密码:
Thread thread = new Thread() {
public void run() {
log.info("Starting...");
new RequestReport().runScheduledTask(requestId);
}
};
thread.start();
private void runScheduledTask(字符串requestId){
log.info(“现在开始五分钟倒计时…”);
ScheduledFuture倒计时=调度程序。调度(()->{
试一试{
新建GetReportList().run(requestId);
}捕获(例外e){
e、 printStackTrace();
}
},5,时间单位(分钟);
试一试{
倒计时;
}捕获(中断异常|执行异常e){
log.info(“捕获的异常”);
e、 printStackTrace();
}
scheduler.shutdown();
}
有没有更好的方法在一个函数运行5分钟后再运行一个函数?我这样做对吗?我应该换什么
顺便说一句,我使用的是spring——有什么东西可以让它变得更好吗?如果您想对代码更“正确”,您可以将RequestReport分离到它自己的实现接口的类中,并将所述类的实例传递给线程的构造函数如果您想对代码更“正确”,您可以将RequestReport分离为实现接口的自己的类,并将所述类的实例传递给线程的构造函数
ScheduledExecutorService
是一个不错的选择,但您使用不当:
首先,您不需要创建一个线程
,只需要从它调度一个任务。它不会增加任何功能,只会浪费资源
其次,在调用shutdown()
后,您的计划程序将不再接受任务,如果您需要生成多个报告,这是不好的
第三,由于任务完成后代码什么也不做,因此根本不需要调用get()
因此,您需要的唯一代码是:
scheduler.schedule(() -> {
try {
new GetReportList().run(requestId);
} catch (Exception e) {
e.printStackTrace();
}
}, 5, TimeUnit.MINUTES);
它将安排任务并立即释放线程。该任务将在五分钟后在由调度程序管理的单独线程中执行
如果您需要对计划任务进行一些控制(检查它们的状态、取消它们等),您可以从schedule()
获取Future
并将其保存在某个位置,但根据您问题中的代码,您不需要它。ScheduledExecutorService
是一个不错的选择,但您使用不当:
首先,您不需要创建一个线程
,只需要从它调度一个任务。它不会增加任何功能,只会浪费资源
其次,在调用shutdown()
后,您的计划程序将不再接受任务,如果您需要生成多个报告,这是不好的
第三,由于任务完成后代码什么也不做,因此根本不需要调用get()
因此,您需要的唯一代码是:
scheduler.schedule(() -> {
try {
new GetReportList().run(requestId);
} catch (Exception e) {
e.printStackTrace();
}
}, 5, TimeUnit.MINUTES);
它将安排任务并立即释放线程。该任务将在五分钟后在由调度程序管理的单独线程中执行
如果您需要对计划的任务进行一些控制(检查它们的状态、取消它们等),您可以从schedule()
获取Future
并将其保存在某个地方,但是根据您问题中的代码,您不需要它。如果您使用的是Spring,您还可以使用@Scheduled
来计划方法调用。但是如何动态地进行?我需要在另一个五分钟后运行任务-程序启动时执行时间未知@SurajBajaj@J.Doe你的while(!countdown.isDone()){}
忙循环是一个非常糟糕的主意。@J.Doe那么它只是在另一个方法调用五分钟后的一次调用吗?我能在没有副作用的情况下摆脱它吗@如果您使用的是Spring,那么您也可以使用@Scheduled
来计划方法调用。但是我如何动态地进行呢?我需要在另一个五分钟后运行任务-程序启动时执行时间未知@SurajBajaj@J.Doe你的while(!countdown.isDone()){}
忙循环是一个非常糟糕的主意。@J.Doe那么它只是在另一个方法调用五分钟后的一次调用吗?我能在没有副作用的情况下摆脱它吗@非常好,非常感谢。这正是我所需要的!Spring是在调用了get()
之后才启动的,但您的解释更有意义……。@J.Doe,请您对“Spring是在调用get()之后才启动的”这句话再详细解释一下好吗?我不认为这个代码会以某种方式影响Spring。也许是别的原因阻止了它的启动?调用get()
时,线程会阻塞并等待任务完成(至少需要五分钟)。我认为您的程序中不需要它(至少它不符合您的描述),因为您的GetReportList.run()
不返回任何内容。是的,就像您所说的那样。我是说在我做你提议的改变之前。现在它工作得非常好-但是当我在函数中有get()
时它没有工作(没有创建新线程),因为它阻止了它。你的答案很好!哦,那好吧。我没有正确理解你的第一句话,我的错。我很高兴这个答案对你有帮助。太好了,非常感谢。这正是我所需要的!Spring是在调用了get()
之后才启动的,但您的解释更有意义……。@J.Doe,请您对“Spring是在调用get()之后才启动的”这句话再详细解释一下好吗?我不认为这个代码会以某种方式影响Spring。也许是别的原因阻止了它的启动?调用get()
时,线程会阻塞并等待任务完成(至少需要五分钟)。我认为你不需要在你的程序中使用它(至少它不是从