使用ScheduledExecutorService在Java中定期运行任务

标记

我正在开发一个程序,该程序将从数据源读取数据,并在读取数据时将其发布。我有一个读取器和一个写入器,读取器产生了几个线程来读取它需要读取的所有数据,将数据放入队列中,然后写入器从队列中读取数据并发布。

我有一个读者专用的控制器和一个作家的控制器。控制器实现了该Callable接口,但是可以实现该Runnable接口,因为我的调用返回是Void

我想使用执行程序来运行两个控制器。阅读器控制器将需要每X分钟调用一次(并且X大于控制器运行所花费的时间)。

现在,我正在创建的列表Callables,将其发送到ExecutorService,即:

List<Future<Void>> futures = ExecutorService es = new Executors.newFixedThreadPoll(2);
for(Future<Void> future: futures) {
    try {
        future.get();
    } catch (Exception e) {
        // log the error
    }
}

如何将其转换为调度执行器,该执行器每30分钟(或更确切地说,在上一次作业运行30分钟后)运行可调用对象?

阿里雷扎·阿霍恩迪

好吧,你可以用几种方法做到这一点。但是,如果性能很重要,则可以在自己的线程中处理这些事情,如下所示:

public class TaskTimer extends Thread {

private java.util.concurrent.LinkedBlockingQueue<Runnable> taskQueue;
private int timeToWait;
private Long lastTime = -1l;

public TaskTimer(int time)
{
    if(time<0)
        throw new IllegalStateException("time can not negative");

    timeToWait = time;
    taskQueue = new java.util.concurrent.LinkedBlockingQueue<>();
}


void  scheduleTask(Runnable task) throws InterruptedException {
    taskQueue.put(task);
}

boolean  tryScheduleTask(Runnable task) {
    return taskQueue.add(task);
}

@Override
public void run() {

    while (true)
    {
        try {
            Runnable a = taskQueue.take();
            if(!(lastTime==-1 || System.currentTimeMillis()-lastTime>timeToWait))
            {
                //so wait !
                synchronized (lastTime)
                {
                    lastTime.wait(timeToWait-(System.currentTimeMillis()-lastTime));
                }

            }
            try{
                a.run();
                lastTime = System.currentTimeMillis();
            }catch (Throwable e)
            {
                //todo handle e
            }
        } catch (InterruptedException e) {

            break;
        }

    }

}
}

而且您也可以像这样使用它:

TaskTimer t = new TaskTimer(2000);
    t.start();
    t.scheduleTask(new Runnable() {
        @Override
        public void run() {
            System.out.println("1");
        }
    });

    t.tryScheduleTask(new Runnable() {
        @Override
        public void run() {
            System.out.println("2");
        }
    });

希望我能为您服务!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

从在ScheduledExecutorService中运行的任务本身中停止定期任务

使用 java.util.TimerTask 在 Java 中定期运行任务

在 Java 中定期运行任务的更好方法

芹菜定期任务未在 Django 中运行

ScheduledExecutorService的任务后运行比预期的

在数据库中存储时运行定期任务

使用kubernetes定期运行非常轻量级的任务

如何从ScheduledExecutorService中删除任务?

使用ScheduledExecutorService安排每月任务

如何有效地取消定期的ScheduledExecutorService任务

如何安排任务定期运行?

使用其他JRE在ant中运行Java任务

如何使用ScheduledExecutorService每天在特定时间运行某些任务?

用芹菜运行另一个定期任务中的任务

如何在Java中安排定期任务?

调用者线程如何等待ScheduledExecutorService下的任务定期完成任务

扩展芹菜中的定期任务

Celery 4.0中的定期任务

如何使用ScheduledExecutorService重新计划任务?

定期运行Celery任务(没有Django)

如何从Java中的ScheduledExecutorService执行所有挂起的计划任务

在Clojure中定期运行任务的最简单方法是什么

是否可以在 Node.js 中运行等效的单独线程来自动定期执行异步任务?

即使关闭应用程序,在后台在Dart和Flutter中运行定期任务

一个清晰的分步过程,用于在Django应用程序中运行定期任务

在没有单独服务器的情况下,使用Django定期运行“任务”

ScheduledExecutorService任务的阻塞时间超过其运行间隔

调度Java中的可运行任务

在运行定期任务之前立即运行Work-WorkManager