java:在特定秒数后运行一个函数

时间:2010-02-13 15:34:35

标签: java timer

我有一个特定的功能,我希望在5秒后执行。 我怎么能用Java做到这一点?

我找到了javax.swing.timer,但我真的不明白如何使用它。看起来我正在寻找比这个类提供的更简单的东西。

请添加一个简单的用法示例。

10 个答案:

答案 0 :(得分:196)

new java.util.Timer().schedule( 
        new java.util.TimerTask() {
            @Override
            public void run() {
                // your code here
            }
        }, 
        5000 
);

修改

javadoc说:

  

在对Timer对象的最后一次实时引用消失并且所有未完成的任务都已完成执行之后,计时器的任务执行线程正常终止(并且变为垃圾回收)。但是,这可能会发生任意长的时间。

答案 1 :(得分:49)

这样的事情:

// When your program starts up
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

// then, when you want to schedule a task
Runnable task = ....    
executor.schedule(task, 5, TimeUnit.SECONDS);

// and finally, when your program wants to exit
executor.shutdown();

Executor上有各种其他工厂方法,如果你想在池中有更多线程,你可以使用它们。

请记住,完成后关闭执行程序非常重要。 shutdown()方法将在最后一个任务完成时干净地关闭线程池,并将阻塞直到发生这种情况。 shutdownNow()将立即终止线程池。

答案 2 :(得分:20)

使用javax.swing.Timer

的示例
Timer timer = new Timer(3000, new ActionListener() {
  @Override
  public void actionPerformed(ActionEvent arg0) {
    // Code to be executed
  }
});
timer.setRepeats(false); // Only execute once
timer.start(); // Go go go!

此代码仅执行一次,执行时间为3000毫秒(3秒)。

正如camickr所提到的,你应该查找“How to Use Swing Timers”作为简短的介绍。

答案 3 :(得分:6)

我的代码如下:

new java.util.Timer().schedule(

    new java.util.TimerTask() {
        @Override
        public void run() {
            // your code here, and if you have to refresh UI put this code: 
           runOnUiThread(new   Runnable() {
                  public void run() {
                            //your code

                        }
                   });
        }
    }, 
    5000 
);

答案 4 :(得分:5)

作为@tangens的变体回答:如果您不能等待垃圾收集器清理线程,请在运行方法结束时取消计时器。

Timer t = new java.util.Timer();
t.schedule( 
        new java.util.TimerTask() {
            @Override
            public void run() {
                // your code here
                // close the thread
                t.cancel();
            }
        }, 
        5000 
);

答案 5 :(得分:4)

你可以使用Thread.Sleep()函数

Thread.sleep(4000);
myfunction();

您的功能将在4秒后执行。然而,这可能会暂停整个计划...

答案 6 :(得分:4)

您的原始问题提及“Swing Timer”。如果实际上你的问题与SWing有关,那么你应该使用Swing Timer而不是util.Timer。

有关详细信息,请阅读“How to Use Timers”上Swing教程中的部分。

答案 7 :(得分:2)

ScheduledThreadPoolExecutor有这种能力,但它非常重量级。

Timer也具有此功能,但即使只使用一次也会打开几个线程。

这是一个简单的测试实现(签名靠近Android' s Handler.postDelayed()):

public class JavaUtil {
    public static void postDelayed(final Runnable runnable, final long delayMillis) {
        final long requested = System.currentTimeMillis();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        long leftToSleep = requested + delayMillis - System.currentTimeMillis();
                        if (leftToSleep > 0) {
                            Thread.sleep(leftToSleep);
                        }
                        break;
                    } catch (InterruptedException ignored) {
                    }
                }
                runnable.run();
            }
        }).start();
    }
}

测试:

@Test
public void testRunsOnlyOnce() throws InterruptedException {
    long delay = 100;
    int num = 0;
    final AtomicInteger numAtomic = new AtomicInteger(num);
    JavaUtil.postDelayed(new Runnable() {
        @Override
        public void run() {
            numAtomic.incrementAndGet();
        }
    }, delay);
    Assert.assertEquals(num, numAtomic.get());
    Thread.sleep(delay + 10);
    Assert.assertEquals(num + 1, numAtomic.get());
    Thread.sleep(delay * 2);
    Assert.assertEquals(num + 1, numAtomic.get());
}

答案 8 :(得分:2)

public static Timer t;

public synchronized void startPollingTimer() {
        if (t == null) {
            TimerTask task = new TimerTask() {
                @Override
                public void run() {
                   //Do your work
                }
            };

            t = new Timer();
            t.scheduleAtFixedRate(task, 0, 1000);
        }
    }

答案 9 :(得分:2)

所有其他unswers都需要在新线程中运行您的代码。 在一些简单的用例中,您可能只想等一下并继续在同一个线程/流程中执行。

下面的代码演示了这种技术。请记住,这与java.util.Timer在幕后的内容类似,但更轻量级。

import java.util.concurrent.TimeUnit;
public class DelaySample {
    public static void main(String[] args) {
       DelayUtil d = new DelayUtil();
       System.out.println("started:"+ new Date());
       d.delay(500);
       System.out.println("half second after:"+ new Date());
       d.delay(1, TimeUnit.MINUTES); 
       System.out.println("1 minute after:"+ new Date());
    }
}

DelayUtil Implementation

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class DelayUtil {
    /** 
    *  Delays the current thread execution. 
    *  The thread loses ownership of any monitors. 
    *  Quits immediately if the thread is interrupted
    *  
    * @param duration the time duration in milliseconds
    */
   public void delay(final long durationInMillis) {
      delay(durationInMillis, TimeUnit.MILLISECONDS);
   }

   /** 
    * @param duration the time duration in the given {@code sourceUnit}
    * @param unit
    */
    public void delay(final long duration, final TimeUnit unit) {
        long currentTime = System.currentTimeMillis();
        long deadline = currentTime+unit.toMillis(duration);
        ReentrantLock lock = new ReentrantLock();
        Condition waitCondition = lock.newCondition();

        while ((deadline-currentTime)>0) {
            try {
                lock.lockInterruptibly();    
                waitCondition.await(deadline-currentTime, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return;
            } finally {
                lock.unlock();
            }
            currentTime = System.currentTimeMillis();
        }
    }
}