简体   繁体   中英

ScheduledExecutorService and scheduled behavior

Is it possible to make ScheduledExecutorService to have one running task and only one waiting task?

  Runnable runnable;
  ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
  private volatile ScheduledFuture<?> self;

 protected void waitAndSweep(final String symbol) {
    try { 

        runnable = new Runnable() {
          @Override
          public void run() {
            try {
              long sweepTime = symbolInfo.getSweepTime(symbol);
              long timeSinceLastSweep = System.currentTimeMillis() - sweepTime;
              long waitTime = timeSinceLastSweep >= getInterval() ? 0 : getInterval() - timeSinceLastSweep;
              logTradeEvent("waitAndSweep", symbol, "waittime: " + waitTime);
              if (waitTime > 0){
                Thread.sleep(waitTime);
              }
              callSweep(symbol);
            } catch (Exception e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
            }            
          }
        };

      self = scheduler.schedule(runnable,0,TimeUnit.SECONDS);


    }catch (Exception e) {
      logEvent(StrategyEntry.ERROR, "waitAndSweep", symbol,
          "Exception caught...", e);
    }
  }

In the above code, assume one runnable task is scheduled by scheduler and it is waiting for 10s (thread.sleep(time)) , in this sleeping time if there is some other task scheduled by scheduler it will wait. Now third task comes into scheduler, then scheduler should not accept it because there is already one running and one waiting task

Do you need to use a ScheduledExecutorService or will a ThreadPoolExecutor do? If so, you can control how many tasks can be queued up at once by creating this yourself (as opposed to using Executors.newFixedThreadPool(1)) and supplying your own queue with a defined capacity like so:

  int  oneThread       = 1;
  long zeroKeepAlive   = 0L;
  int  queueDepthOfOne = 1;

  ThreadPoolExecutor threadPoolExecutor =
        new ThreadPoolExecutor(
              oneThread,
              oneThread,
              zeroKeepAlive,
              TimeUnit.MILLISECONDS,
              new ArrayBlockingQueue<Runnable>(queueDepthOfOne)
        );

Also, you could do this with a little less configuration by using the ThreadPoolTaskExecutor class from the spring framework:

ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setQueueCapacity(1);

ThreadPoolTaskExecutor API docs: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM