java—每隔一段时间调用一个函数
我有一个程序,可以在其中插入一个文件路径及其对应的参数到一个表中 之后,我有另一个函数,名为java—每隔一段时间调用一个函数,java,Java,我有一个程序,可以在其中插入一个文件路径及其对应的参数到一个表中 之后,我有另一个函数,名为do\u Scan() 它扫描表并对其进行一些处理和索引 但是,我希望这个函数do_Scan()以一定的间隔运行,比如说每N分钟运行一次,然后它就会调用这个函数。N是绝对可配置的 我正在考虑使用计时器类,但不太确定如何实现配置。我的想法是创建一个计时器函数,它将调用do\u Scan方法 课程应该是这样的: public void schedule(TimerTask task,long delay,lo
do\u Scan()
它扫描表并对其进行一些处理和索引
但是,我希望这个函数do_Scan()
以一定的间隔运行,比如说每N分钟运行一次,然后它就会调用这个函数。N是绝对可配置的
我正在考虑使用计时器类,但不太确定如何实现配置。我的想法是创建一个计时器函数,它将调用do\u Scan
方法
课程应该是这样的:
public void schedule(TimerTask task,long delay,long period){
}
我的主要方法是:
public static void main(String[] args) throws Exception {
Indexing test= new Indexing();
java.sql.Timestamp date = new java.sql.Timestamp(new java.util.Date().getTime());
// Exception e=e.printStackTrace();
Scanner scanner = new Scanner(System.in);
System.out.print("Enter a file path: ");
System.out.flush();
String filename = scanner.nextLine();
File file = new File(filename);
if(file.exists() && !file.isDirectory()) {
test.index_request(filename,"Active",date,date,"");
}else{
test.index_request(filename,"Error",date,date,"Some errorCode");
}
// Call schedule() function
}}
如何设置Timer类,使其无限期地运行一定的时间间隔?为此,我建议您使用Java的
ScheduledExecutorService
,它为您提供了一个API,可以按固定速率(以及其他API)调度任务
您有两个选项可以执行此操作:
Runnable
或Callable
(或类似)并调用schedule()
方法:
public class IndexingTask implements Runnable {
@Override
public void run() {
schedule();
}
private void schedule() {
//do something
}
}
public static void main(String[] args) {
//do some stuff
long delay = getDelay();
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
scheduledThreadPool.scheduleAtFixedRate(new IndexingTask(), 0, delay, TimeUnit.SECONDS);
}
public static void main(String[] args) {
//do some stuff
long delay = getDelay();
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
scheduledThreadPool.scheduleAtFixedRate(() -> doSomething(), 0, delay, TimeUnit.SECONDS);
}
@Scheduled
注释,如下所示:
@Scheduled(fixedRate = 5000)
public void schedule() {
//do something
}
有很多方法可以解决这个问题。我认为最简单的方法是,当您仅在给定位置使用此方法,而不使用Spring之类的外部框架时:
private void runWithInterval(long millis) {
Runnable task = () -> {
try {
while (true) {
Thread.sleep(millis);
// payload
}
} catch(InterruptedException e) {
}
};
Thread thread = new Thread(task);
thread.setDaemon(true);
thread.start();
}
要以1分钟的间隔调用它,请执行以下操作:
runWithInterval(时间单位:分钟:1)
p.S.
您可以在此处的其他帖子中看到其他方式的详细信息:
使用@Scheduler
Spring时的注释
- 将线程池与单线程一起使用:
ScheduledExecutorService scheduledThreadPool=Executors.newFixedThreadPool(1)
- 使用
:Timer
new Timer().schedule(new Runnable(){},TimeUnit.MINUTES.toMillis(1))
- 最简单的方法是使用标准库中的类
java.util.Timer
下面是一个使用它的简单示例:
import java.util.Timer;
import java.util.TimerTask;
class MyTask extends TimerTask
{
public static int i = 0;
public void run()
{
System.out.println("Hello, I'm timer, running iteration: " + ++i);
}
}
public class Test
{
public static void main(String[] args)
{
Timer timer = new Timer();
TimerTask task = new MyTask();
timer.schedule(task, 2000, 5000); // 2000 - delay (can set to 0 for immediate execution), 5000 is a frequency.
}
}
如果您熟悉java库,可以将其用作:
Flowable.interval(1, TimeUnit.SECONDS) // Or any other desired interval
.subscribe(iteration -> System.out.println("Hello, I'm timer, running iteration: " + iteration));
但您确实应该阅读更多有关此方法和库的信息您可以通过使用
ScheduledThreadPoolExecutor
实现这一点:
假设您有一个任务方法:
public void task(String foo, Integer bar){
// ...
}
在Java 1.8之前
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2);
executor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
task(fooParam, barParam);
}
}, 0, 60, TimeUnit.SECONDS);
Java1.8+
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
executor.scheduleAtFixedRate(() -> task(fooParam, barParam), 0, 60, TimeUnit.SECONDS);
例子?但是我想让计时器发挥它自己的功能,看看这是否对你有帮助是的,确实有帮助。这是实现这一目标的最佳方式吗?建议
Runnable
的答案相当古老。改用lambdas(从java 1.8开始)。如果其中出现任何错误,那么我需要编写另一个函数来处理它。是的,当然,但这是您的自定义逻辑,取决于应用程序。计时器只提供周期性运行某些内容的功能。这并不能避免处理错误。这种方法会导致漂移,因为有效载荷会影响计时。