簡體   English   中英

如果上一個未完成,如何不啟動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毫秒后執行它。 計數應為要使用的線程數,可接受1。 這也使您可以在將來停止任務。

您的示例存在的問題。 a)您正在執行程序線程上睡覺。 不要這樣做,讓執行者來處理它。 如果您使用的線程池為1,則該執行程序在等待時無法執行任何工作。 b)啟動一個新線程正在從執行者那里獲得控制權...僅使用執行者,您就可以對執行進行一些控制。

如果您真的想堅持使用表格。

class RecurringTask implements Runnable{
    @Override
    public void run(){
        doJob();
        executor.schedule(this, delay, TimeUnit.MILLISECONDS); 
    }
}

現在,您將創建從未使用過的期貨,因此將更加難以控制任務的執行。

在任務類中創建靜態成員-鎖定。 在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM