Java 在新线程中运行调度

Java 在新线程中运行调度,java,multithreading,scheduledexecutorservice,Java,Multithreading,Scheduledexecutorservice,我正在查询API以创建报告,并希望在5分钟后加载该报告。我想使用一个ScheduledExecutorService。由于我不希望执行者阻止我的线程,我正在为此创建一个新线程,但我不确定这是否是正确的方法。这是我的密码: Thread thread = new Thread() { public void run() { log.info("Starting..."); new RequestReport().runSchedule

我正在查询API以创建报告,并希望在5分钟后加载该报告。我想使用一个
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()
时,线程会阻塞并等待任务完成(至少需要五分钟)。我认为你不需要在你的程序中使用它(至少它不是从