如果前一个未完成,如何不启动 ScheduledExecutorService 任务
How not to start ScheduledExecutorService task if previous one is not finished
我的问题是我们必须给它一个固定的 计划时间以使其启动任务。假设我给了 10 秒,我的任务平均完成时间为 10-15 秒。因此,在 quque 中等待线程一段时间后会导致巨大的内存消耗。如果我使用 syncronized
作为上述方法,就会出现问题。如果我不使用 syncronized
那么我就是在浪费资源 (cpu),因为如果没有完成我不需要 运行 任务。所以我想到了任务递归调用的解决方案,但我相信递归线程会增加更多的内存问题……我该怎么办?很快我只想在任务完成时调用它。时间不定
public void myScheduledTask{
doJob(); ( use countdown latch to control waiting if necessary)
TimeUnit.SECONDS.sleep(x);
new Thread( new Runnable( { mySchedulTask(); } ));
or
executor.execute( a thread that call myScheduledTask() method);
}
听起来像您想要完成的选项:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(count);
ScheduledFuture<?> future = executor.scheduleWithFixedDelay(
task,
delay,
delay,
TimeUnit.MILLISECONDS
);
这将启动您的任务并在上次完成后 delay
毫秒后执行。 Count 应该是你要使用的线程数,1 是可以接受的。这也让您可以使用 future 停止任务。
你的例子有问题。 a) 您正在执行程序线程上休眠。不要这样做让执行者处理它。如果您使用的线程池为 1,则此执行程序在您等待期间无法执行任何工作。 b) 启动一个新线程是从执行程序中获取控制权...只需使用执行程序,然后您就可以控制执行。
如果你真的想坚持现有的形式。
class RecurringTask implements Runnable{
@Override
public void run(){
doJob();
executor.schedule(this, delay, TimeUnit.MILLISECONDS);
}
}
现在您将创建从未使用过的 Future,因此将更难控制任务的执行。
在您的任务中创建静态成员class - 锁定。
如果已经获得锁,在 doJob 中避免执行作业:
if (lock.tryLock()) {
try {
// do the job
} finally {
lock.unlock();
}
} else {
// log the fact you skipped the job
return;
}
我的问题是我们必须给它一个固定的 计划时间以使其启动任务。假设我给了 10 秒,我的任务平均完成时间为 10-15 秒。因此,在 quque 中等待线程一段时间后会导致巨大的内存消耗。如果我使用 syncronized
作为上述方法,就会出现问题。如果我不使用 syncronized
那么我就是在浪费资源 (cpu),因为如果没有完成我不需要 运行 任务。所以我想到了任务递归调用的解决方案,但我相信递归线程会增加更多的内存问题……我该怎么办?很快我只想在任务完成时调用它。时间不定
public void myScheduledTask{
doJob(); ( use countdown latch to control waiting if necessary)
TimeUnit.SECONDS.sleep(x);
new Thread( new Runnable( { mySchedulTask(); } ));
or
executor.execute( a thread that call myScheduledTask() method);
}
听起来像您想要完成的选项:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(count);
ScheduledFuture<?> future = executor.scheduleWithFixedDelay(
task,
delay,
delay,
TimeUnit.MILLISECONDS
);
这将启动您的任务并在上次完成后 delay
毫秒后执行。 Count 应该是你要使用的线程数,1 是可以接受的。这也让您可以使用 future 停止任务。
你的例子有问题。 a) 您正在执行程序线程上休眠。不要这样做让执行者处理它。如果您使用的线程池为 1,则此执行程序在您等待期间无法执行任何工作。 b) 启动一个新线程是从执行程序中获取控制权...只需使用执行程序,然后您就可以控制执行。
如果你真的想坚持现有的形式。
class RecurringTask implements Runnable{
@Override
public void run(){
doJob();
executor.schedule(this, delay, TimeUnit.MILLISECONDS);
}
}
现在您将创建从未使用过的 Future,因此将更难控制任务的执行。
在您的任务中创建静态成员class - 锁定。 如果已经获得锁,在 doJob 中避免执行作业:
if (lock.tryLock()) {
try {
// do the job
} finally {
lock.unlock();
}
} else {
// log the fact you skipped the job
return;
}