【问题标题】:Scheduling a task in java在java中调度任务
【发布时间】:2014-04-14 18:45:00
【问题描述】:

在我的 java web 应用程序中,我想安排一个任务。

我在网上搜索了很多,但找不到适合我的情况的调度程序。在应用程序中,我有不同类型的用户。对于特定的用户类型,我想安排一个任务。

当用户采取关键行动时:

  • 我想在 15 分钟后向该特定用户发送电子邮件
  • 我想在 30 分钟后发送另一封电子邮件
  • 我想发送另一封电子邮件并关闭调度程序。

我知道用户何时采取关键行动以及如何发送电子邮件,但我没有太多关于安排的经验。

谁能帮我处理这个案子?

【问题讨论】:

  • 你可能想在 critical 动作发生时发送Thread

标签: java scheduled-tasks timertask


【解决方案1】:

为什么不使用 ScheduledExecutor? http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html

它有一个方法schedule,它允许你安排你想要的任何任务(你传递一个runnable)。因此,基本上,您可以为每个用户安排一个发送电子邮件的任务并安排另一个任务。

import static java.util.concurrent.TimeUnit.*;

class Task implements Runnable {
   private final User user;
   private final int rep;
   private final ScheduledExecutorService scheduler;

   public Task(User user, int rep, ScheduledExecutorService scheduler) {
       this.user = user;
       this.rep = rep;
       this.scheduler = scheduler;
   }

   public void run() {
       // send an e-mail to user
       if (rep > 0)
           scheduler.schedule(new Task(user, rep - 1, scheduler), 15, MINUTES);
   }
}

class Example {
    private final ScheduledExecutorService scheduler =
        Executors.newScheduledThreadPool(1);

    public void sendEmails() {
        // foreach user
        scheduler.submit(new Task(user, 3, scheduler));
    }
}

您可能希望使用具有多个线程的计划线程池。

【讨论】:

  • 您能帮我使用 ManagedScheduledExecutorService 创建相同的任务吗?我需要创建一个每天下午 5 点运行的作业。它是网络应用程序。查了很多还是没完成
  • @ShwetaMishra 为什么不将schedule 方法与Trigger 一起使用?这里的第二个示例几乎正是您所需要的:docs.oracle.com/javaee/7/api/javax/enterprise/concurrent/…
  • 感谢您的回复。实际上它是一个 Web 应用程序,我必须使用 ManagedScheduledExecutorService 类。 ScheduledExecutorService 类的问题是,如果出现任何异常,它只会报告。但是代码崩溃了。
  • @ShwetaMishra 我不确定 ManagedScheduledExecutorService 和 ScheduledExecutorService 在异常处理方面有何不同,但我建议使用 ManagedScheduledExecutorService schedule 方法。如果它不能解决您的问题,请考虑在 SO 上发布一个单独的问题。
【解决方案2】:

使用Quartz Scheduler 安排任务

需要的步骤 -

1) 石英作业

public class HelloJob implements Job {
    public void execute(JobExecutionContext context) throws JobExecutionException {
    System.out.println("Hello Quartz!");    
    }
}

2) 创建触发器 - CronTrigger - 每 30 秒运行一次

CronTrigger trigger = new CronTrigger();
trigger.setName("dummyTriggerName");
trigger.setCronExpression("0/30 * * * * ?");

3) 创建调度器

Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);

【讨论】:

    【解决方案3】:

    这里有一个关于如何使用 Java 定时器的教程: http://enos.itcollege.ee/~jpoial/docs/tutorial/essential/threads/timer.html

    您可以按顺序创建多个计时器任务来实现您的目标。

    示例 代码引用:

    import java.util.Timer;
    import java.util.TimerTask;
    
    /**
     * Simple demo that uses java.util.Timer to schedule a task 
     * to execute once 5 seconds have passed.
     */
    
    public class Reminder {
    Timer timer;
    
    public Reminder(int seconds) {
        timer = new Timer();
        timer.schedule(new RemindTask(), seconds*1000);
    }
    
    class RemindTask extends TimerTask {
        public void run() {
            System.out.format("Time's up!%n");
            timer.cancel(); //Terminate the timer thread
        }
    }
    
    public static void main(String args[]) {
        new Reminder(5);
        System.out.format("Task scheduled.%n");
    }
    }
    

    【讨论】:

      【解决方案4】:

      我建议你看看石英调度 API http://quartz-scheduler.org/

      到目前为止,我已经在多个项目中使用过它,它非常容易设置和配置新作业。它支持基于 cron 的触发器或简单触发器,因此您可以在 java 代码中计算预定事件的时间,也可以只需传递一个 cron 字符串。

      另一个优点是它真的很容易用 spring 配置。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-20
        • 2011-01-08
        • 2021-10-15
        • 2012-06-29
        • 2012-10-06
        • 2020-03-28
        • 2020-10-21
        • 1970-01-01
        相关资源
        最近更新 更多