如何在Java中设置计时器?

如何在Java中设置计时器?,java,timer,Java,Timer,如何设置一个计时器,比如说2分钟,尝试连接到数据库,然后在连接中出现任何问题时抛出异常?因此,答案的第一部分是如何做主题要求的事情,因为这是我最初解释它的方式,一些人似乎觉得很有帮助。这个问题后来被澄清了,我扩展了答案来解决这个问题 设置计时器 首先,您需要创建一个计时器(我在这里使用的是java.util版本): 要运行任务,请执行以下操作: timer.schedule(new TimerTask() { @Override public void run() { // Y

如何设置一个计时器,比如说2分钟,尝试连接到数据库,然后在连接中出现任何问题时抛出异常?

因此,答案的第一部分是如何做主题要求的事情,因为这是我最初解释它的方式,一些人似乎觉得很有帮助。这个问题后来被澄清了,我扩展了答案来解决这个问题

设置计时器

首先,您需要创建一个计时器(我在这里使用的是
java.util
版本):

要运行任务,请执行以下操作:

timer.schedule(new TimerTask() {
  @Override
  public void run() {
    // Your database code here
  }
}, 2*60*1000);
// Since Java-8
timer.schedule(() -> /* your database code here */, 2*60*1000);
timer.scheduleAtFixedRate(new TimerTask() {
  @Override
  public void run() {
    // Your database code here
  }
}, 2*60*1000, 2*60*1000);

// Since Java-8
timer.scheduleAtFixedRate(() -> /* your database code here */, 2*60*1000, 2*60*1000);
要在持续时间后重复任务,请执行以下操作:

timer.schedule(new TimerTask() {
  @Override
  public void run() {
    // Your database code here
  }
}, 2*60*1000);
// Since Java-8
timer.schedule(() -> /* your database code here */, 2*60*1000);
timer.scheduleAtFixedRate(new TimerTask() {
  @Override
  public void run() {
    // Your database code here
  }
}, 2*60*1000, 2*60*1000);

// Since Java-8
timer.scheduleAtFixedRate(() -> /* your database code here */, 2*60*1000, 2*60*1000);
使任务超时

要具体执行澄清问题所要求的,即在给定时间段内尝试执行任务,您可以执行以下操作:

ExecutorService service = Executors.newSingleThreadExecutor();

try {
    Runnable r = new Runnable() {
        @Override
        public void run() {
            // Database task
        }
    };

    Future<?> f = service.submit(r);

    f.get(2, TimeUnit.MINUTES);     // attempt the task for two minutes
}
catch (final InterruptedException e) {
    // The thread was interrupted during sleep, wait or join
}
catch (final TimeoutException e) {
    // Took too long!
}
catch (final ExecutionException e) {
    // An exception from within the Runnable task
}
finally {
    service.shutdown();
}
ExecutorService service=Executors.newSingleThreadExecutor();
试一试{
Runnable r=新的Runnable(){
@凌驾
公开募捐{
//数据库任务
}
};
未来f=服务提交(r);
f、 获取(2,TimeUnit.MINUTES);//尝试执行该任务两分钟
}
捕获(最终中断异常e){
//线程在睡眠、等待或加入期间被中断
}
捕获(最终超时例外e){
//时间太长了!
}
捕获(最终执行例外){
//可运行任务中的异常
}
最后{
service.shutdown();
}
如果任务在2分钟内完成,这将正常执行,但有例外。如果它的运行时间超过此值,则会抛出TimeoutException


一个问题是,尽管在两分钟后您会得到一个TimeoutException,但任务实际上会继续运行,尽管数据库或网络连接可能最终会超时并在线程中抛出异常。但请注意,在这种情况发生之前,它可能会消耗资源。

好的,我想我现在理解你的问题了。你可以使用未来来尝试做一些事情,如果什么都没有发生,那么在一段时间后超时

例如:

FutureTask task=newfuturetask(newcallable()){
@凌驾
public Void call()引发异常{
//做数据库工作
返回null;
}
});
Executor Executor=Executors.newSingleThreadScheduledExecutor();
执行者。执行(任务);
试一试{
任务。获取(5,时间单位。秒);
}
捕获(例外情况除外){
//处理您的异常
}
使用此

long startTime = System.currentTimeMillis();
long elapsedTime = 0L.

while (elapsedTime < 2*60*1000) {
    //perform db poll/check
    elapsedTime = (new Date()).getTime() - startTime;
}

//Throw your exception
long startTime=System.currentTimeMillis();
长时间延迟时间=0升。
同时(延时<2*60*1000){
//执行数据库轮询/检查
elapsedTime=(新日期()).getTime()-startTime;
}
//抛出你的异常

[Android]如果有人希望使用java在Android上实现计时器

您需要像这样使用UI线程来执行操作


哦,我猜你们把我的问题搞错了,我必须反复尝试连接到数据库,直到每次2分钟。读者们注意:这个答案显然是错的。它将计时器设置为等待2分钟,然后在延迟2分钟后运行DB查询,然后每隔2分钟一次又一次地运行。它没有做的是立即运行DB查询,然后在2分钟后失败,这就是我认为问题所要求的(如评论中所澄清的)。@AgilePro这是真的。我没有回答最终提出的问题,现在我更新了它以解决这个问题。@Ernestatsgruodis核心API将构造函数列为公共的:您的类路径中可能有不同的Timer类-尝试使用java.util.Timer作为类。如何将Timer.schedule()与lambda表达式一起使用(从java 8开始)?TimerTask(第一个参数)甚至不是功能接口。TimerTask只是一个抽象类。会引发异常,但程序不会终止。请帮助我解决此问题。您可以使用ExecutorService类而不是Executor。它有shutdown()方法来停止执行器。执行器将吞下抛出的异常,这些异常不是您在Callable/Runnable中特别处理的。如果Runnable/Callable本身没有捕获和处理异常,并且它是提供给您的,而您拥有它,那么您需要对ScheduledExecutorService进行子类化,并重写afterExecute(确保调用super.afterExecute())。afterExecute的第二个参数是Runnable/Callablehmm中的可丢弃参数。。。这在技术上是可行的,但不包括边缘情况,即在执行DB轮询时,您的时间不多了,这可能是OPC要求的。这是唯一正确的答案。它将在单个线程上运行,并将计算无漂移的结束时间。在这种情况下,使用TimerTask完全是错误的。我很惊讶有多少关于StackOverflow的例子表明了这种错误的想法。@Coshman-计时器的实现不会在数据库运行过程中中断,这也不会。在任何情况下,您只能控制启动DB操作的时间。有一个常见的误解是,你需要一个“计时器”来计时,但你不需要。你只需要做一些事情,使用当前时间确保不要做得太长。假设你必须在两分钟后返回连接或抛出,这将不起作用。如果在尝试连接两分钟后仍无法连接,则会发生此问题。在连接检查需要两周的情况下,抛出异常需要很长时间。这实际上是非常糟糕的编码方式,因为while循环不断运行并检查内容。。。对cpu和电池寿命有害。请让OP澄清他们是否希望简单地尝试操作至少2分钟,或者如果两分钟后必须立即抛出异常,即使当前正在尝试连接,只要复制上面的代码即可。我已经给出了两次“时间”,第一次是第一次执行此代码,第二次是间隔时间
long startTime = System.currentTimeMillis();
long elapsedTime = 0L.

while (elapsedTime < 2*60*1000) {
    //perform db poll/check
    elapsedTime = (new Date()).getTime() - startTime;
}

//Throw your exception
    new java.util.Timer().schedule(new TimerTask(){
        @Override
        public void run() {
            System.out.println("Executed...");
           //your code here 
           //1000*5=5000 mlsec. i.e. 5 seconds. u can change accordngly 
        }
    },1000*5,1000*5); 
Timer timer = new Timer();
timer.schedule(new TimerTask() {
           @Override
            public void run() {
                ActivityName.this.runOnUiThread(new Runnable(){
                    @Override
                      public void run() {
                       // do something
                      }        
                });
            }
        }, 2000));