[翻译] 在JAVA中,怎样周期性运行一个任务

原文出处:http://www.codelast.com/

本文是对这篇文章的翻译:《How to Schedule a Task to Run in an Interval》
我不知道原作者是否允许这样做,但我翻译本文仅在于传播知识的目的,在此向原作者表示深深的感谢:感谢你们的分享。

在程序中通常都有在后台周期性运行某些任务的需求。例如,类似于Java垃圾收集的后台运行任务。
我将在本文中向你展示3种不同的实现方法,如下:
  • 使用简单的线程
  • 使用TimerTask
  • 使用ScheduledExecutorService
文章来源: http://www.codelast.com/
  • 使用简单的线程
这个方法非常简单:创建一个线程,使用while循环让它永久运行,并利用sleep方法在运行中插入时间间隔。
 
这是个简单又快的实现方法。
代码示例如下:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Task1 {
public static void main(String[] args) {
   // run in a second
   final long timeInterval = 1000 ;
   Runnable runnable = new Runnable() {
   public void run() {
     while ( true ) {
       // ------- code for task to run
       System.out.println( "Hello !!" );
       // ------- ends here
       try {
        Thread.sleep(timeInterval);
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
       }
     }
   };
   Thread thread = new Thread(runnable);
   thread.start();
   }
}

文章来源:http://www.codelast.com/

  • 使用Timer和TimerTask

之前我们看到的方法极其简单快速,但是它缺少一些功能。

这个方法比之前的方法有更多好处:
可以控制什么时候开始、取消任务;
如果愿意的话,可以延迟第一次执行时间,这个特性很有用。
在本例中, Timer类是用于schedule的, TimerTask类是用于包装在它里面的run()方法中执行的任务。
Timer实例可以共享,用于schedule多个任务,并且它是线程安全的。
当Timer类的构造函数被调用的时候,就创建了一个线程,并且这个单独的线程可用于schedule任务。
为了实现我们的目的,我们使用 Timer类的scheduleAtFixedRate方法
下面的代码展示了Timer类和TimerTask类的使用方法:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
import java.util.Timer;
import java.util.TimerTask;
public class Task2 {
   public static void main(String[] args) {
     TimerTask task = new TimerTask() {
       @Override
       public void run() {
         // task to run goes here
         System.out.println( "Hello !!!" );
       }
     };
     Timer timer = new Timer();
     long delay = 0 ;
     long intevalPeriod = 1 * 1000 ;
     // schedules the task to be run in an interval
     timer.scheduleAtFixedRate(task, delay,
                                 intevalPeriod);
   } // end of main
}

从JDK 1.3开始这些类就已经有了。
文章来源:http://www.codelast.com/

  • 使用ScheduledExecutorService

这个类是从Java SE 5开始作为并发工具引入的,位于包java.util.concurrent中。

与之前的解决方案相比,它提供了如下好处:
用线程池来执行任务,而之前的Timer类是单线程的。
提供了第一次任务延迟执行的灵活性。
提供了设置时间间隔的良好惯例。
 
下面的代码展示了使用方法。
在本例中,我们使用了 ScheduledExecutorService类的scheduleAtFixedRate方法,它接受一个Runnable对象作为参数(其包含了要周期性运行的代码),以及第一次执行任务的延迟时间。

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Task3 {
   public static void main(String[] args) {
     Runnable runnable = new Runnable() {
       public void run() {
         // task to run goes here
         System.out.println( "Hello !!" );
       }
     };
     ScheduledExecutorService service = Executors
                     .newSingleThreadScheduledExecutor();
     service.scheduleAtFixedRate(runnable, 0 , 1 , TimeUnit.SECONDS);
   }
}

你可能感兴趣的:(JAVA)