[英]How not to start ScheduledExecutorService task if previous one is not finished
My problem is we have to give it a fixed schedule time to make it start task. 我的问题是我们必须给它固定的时间表时间以使其开始任务。 Lets say i give 10 seconds and my task has average finish time of 10-15 seconds.
可以说我给了10秒,我的任务平均完成时间为10-15秒。 Thus after some time waiting threads in quque causes huge memory consumption.
因此,经过一段时间后,quque中的等待线程会导致大量内存消耗。 If i use
syncronized
for the method above problem will occur. 如果我将
syncronized
用于上述方法,则会出现问题。 If i don't use syncronized
then i am wasting resources ( cpu) because i dont need to run task if not finished. 如果我不使用
syncronized
那么我正在浪费资源(cpu),因为如果没有完成,我不需要运行任务。 So i thought a solution of recursive call of task but i believe recursive threads will add more memory problems... what should i do? 因此,我想到了递归调用任务的解决方案,但我相信递归线程将增加更多的内存问题...我该怎么办? Shortly i just want to be able to call a task when it is finished.
不久,我只希望能够在完成任务时调用它。 Not fixed time.
时间不固定。
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);
}
The option that sounds like what you're trying to accomplish: 听起来像您要完成的选择:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(count);
ScheduledFuture<?> future = executor.scheduleWithFixedDelay(
task,
delay,
delay,
TimeUnit.MILLISECONDS
);
This would start your task and execute it after delay
milliseconds after the previous completion. 这将启动您的任务,并在上一次完成后
delay
毫秒后执行它。 Count should be the number of threads you want to use, 1 is acceptable. 计数应为要使用的线程数,可接受1。 This also lets you stop the task using the future.
这也使您可以在将来停止任务。
The problems with your example. 您的示例存在的问题。 a) You are sleeping on an executor thread.
a)您正在执行程序线程上睡觉。 Dont do this let the executor handle it.
不要这样做,让执行者来处理它。 If you were using a threadpool of 1 then this executor couldn't do any work while you're waiting.
如果您使用的线程池为1,则该执行程序在等待时无法执行任何工作。 b) Starting a new thread is taking control from the executor... just use the executor, then you have some control over the execution.
b)启动一个新线程正在从执行者那里获得控制权...仅使用执行者,您就可以对执行进行一些控制。
If you really wanted to stick with the form you have. 如果您真的想坚持使用表格。
class RecurringTask implements Runnable{
@Override
public void run(){
doJob();
executor.schedule(this, delay, TimeUnit.MILLISECONDS);
}
}
Now you will be creating Futures that you never use, so it will be harder to control the execution of the task. 现在,您将创建从未使用过的期货,因此将更加难以控制任务的执行。
Create static member in your task class - Lock. 在任务类中创建静态成员-锁定。 In doJob avoid performing job if lock is already aquired :
在doJob中,如果已经获得锁定,请避免执行作业:
if (lock.tryLock()) {
try {
// do the job
} finally {
lock.unlock();
}
} else {
// log the fact you skipped the job
return;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.