创建后台线程的最佳方法是什么,每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进行比较?
哪种方式更好?
如果有更好的方法,我的代码的任何示例基础都会受到赞赏。
答案 0 :(得分:11)
ScheduledExecutorService将返回一个Future,它有一个额外的方法来检查Runnable是否已完成。两者都有取消Runnable的方法。对于像这样的重复任务,检查它是否已完成,可能不会有多大用处。但是,它是用jdk 1.5并发api引入的,它绝对应该用来代替旧的并发/线程api(Timer和TimerTask是jdk 1.3)。它们将更强大,性能更好。它们与java doc here中的用例非常相似。
这是一个样本:
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();
}
}
答案 1 :(得分:2)
您可以尝试使用java.util.TimerTask和java.util.Timer
示例是here: -
Timer t = new Timer();
t.scheduleAtFixedRate(
new TimerTask()
{
public void run()
{
System.out.println("3 seconds passed");
}
},
0, // run first occurrence immediately
3000);
答案 2 :(得分:0)
tieTYT是对的。如果在应用程序服务器中使用它,则可以使用特定服务器的ejbtimer服务