7

创建每 15 分钟运行一次以从数据库中获取数据的后台线程的最佳方法是什么?

下面是我拥有的代码,我猜它在生产中可以正常工作,但还有其他更好的方法吗?或者我应该注意什么?

private static void checkDatabaseEveryXMinutes() {
    new Thread() {
        public void run() {
            while (true) {
                try {
                    Thread.sleep(checkingAfterEveryXMinutes);
                    getDataFromDatabase();
                } catch (InterruptedException ex) {
                    //log here
                } catch (Exception e) {
                    //log here
                }
            }
        }
    }.start();
}

使用上面的代码有什么缺点吗?ScheduledExecutorService 与 TimerTask 相比如何?

哪种方式更好?

如果有任何更好的方法,我的代码的任何示例基础都将受到赞赏。

4

3 回答 3

11

ScheduledExecutorService 将返回一个 Future,它有一个额外的方法来检查 Runnable 是否完成。两者都有取消 Runnable 的方法。对于像这样的重复任务,检查它是否完成,可能不会有太大用处。但是,它是由 jdk 1.5 并发 api 引入的,它绝对应该用来代替旧的并发/线程 api(Timer 和 TimerTask 是 jdk 1.3)。它们将更健壮,性能更好。他们在此处的 java doc 中有一个与您的用例非常相似的示例。

这是一个示例:

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

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

    public void startScheduleTask() {
    /**
    * not using the taskHandle returned here, but it can be used to cancel
    * the task, or check if it's done (for recurring tasks, that's not
    * going to be very useful)
    */
    final ScheduledFuture<?> taskHandle = scheduler.scheduleAtFixedRate(
        new Runnable() {
            public void run() {
                try {
                    getDataFromDatabase();
                }catch(Exception ex) {
                    ex.printStackTrace(); //or loggger would be better
                }
            }
        }, 0, 15, TimeUnit.MINUTES);
    }

    private void getDataFromDatabase() {
        System.out.println("getting data...");
    }

    public void shutdowh() {
        System.out.println("shutdown...");
        if(scheduler != null) {
            scheduler.shutdown();
        }
    }

    public static void main(String[] args) {
        final ScheduledTaskExample ste = new ScheduledTaskExample();
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                ste.shutdowh();
            }
        });
        ste.startScheduleTask();

    }
}
于 2013-08-21T20:42:58.147 回答
2

您可以尝试使用java.util.TimerTaskjava.util.Timer

示例在这里:-

Timer t = new Timer();

t.scheduleAtFixedRate(
    new TimerTask()
    {
        public void run()
        {
            System.out.println("3 seconds passed");
        }
    },
    0,      // run first occurrence immediately
    3000);
于 2013-08-21T19:18:13.150 回答
0

tieTYT 是对的。如果在应用服务器中使用,可以使用特定服务器的ejbtimer服务

于 2013-08-21T19:21:15.973 回答