在java中创建后台线程的最佳方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18365795/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:54:43  来源:igfitidea点击:

Best way to create a background thread in java

javamultithreadingbackground-thread

提问by arsenal

What is the best way to create a background thread that will run every 15 minutes to get the data from the database?

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

Below is the code I have which will work fine I guess in production but is there any other way better that I have or something that I should be aware of?

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

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();
}

Is there any disadvantage in using the above code. And how does ScheduledExecutorService compares with TimerTask?

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

Which way is better?

哪种方式更好?

Any example basis on my code will be appreciated on this if there are any better approach.

如果有更好的方法,我将不胜感激任何基于我的代码的示例。

采纳答案by Alper Akture

ScheduledExecutorService will return you a Future that has an additional method to check if the Runnable completed. Both have methods for canceling the Runnable. For repeated task like this, checking if it's done, is probably not going to be of much use. However, it was introduced with jdk 1.5 concurrency api, which should definitely be used in place of older concurrency/thread api's (Timer and TimerTask were jdk 1.3). They will be more robust, and better performant. They have a very similar example as your use case in the java doc here.

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

here's a sample:

这是一个示例:

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();

    }
}

回答by Rahul Tripathi

You can try using java.util.TimerTaskand java.util.Timer

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

Example is here:-

例子在这里:-

Timer t = new Timer();

t.scheduleAtFixedRate(
    new TimerTask()
    {
        public void run()
        {
            System.out.println("3 seconds passed");
        }
    },
    0,      // run first occurrence immediately
    3000);

回答by ssdimmanuel

tieTYT is right. If you are using it in an application server, you can use the ejbtimer service of the specific server

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