Search code examples
javamultithreadingsleep

How to invoke some code once after and additional to a Thread.sleep


Imagine having this code running in a Thread:

while (blockingQueue.size() > 0) {
    
    AbortableCountDownLatch latch = (AbortableCountDownLatch) blockingQueue.poll();
    latch.countDown();
}
Thread.sleep(updateinterval * 1000);

How to make the while loop run after the Thread.sleep as an additional execution? As something like:

Thread.sleepAndExecute(Runnable code, sleep time);

So that the code is just executed, after the sleep has entered, not the other way around?

The blockingQueue contains some CountDownLatch, which are blocking another thread. The other thread just is allowed to continue, IF the latches are all countdown AND this thread has entered sleep/await state. Both conditions need to be true so that the other thread is allowed to continue.


Solution

  • The point is that you should not be needing to sleep. You can use CompleteableFurture API thenCombine to combine the two tasks.

    Code below:

    CompletableFuture.runAsync(() -> {
      while (blockingQueue.size() > 0) {
        try {
          System.out.println("Sleeping in thread - " + Thread.currentThread().getName());
          Thread.sleep(1000l);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }).thenCombine(CompletableFuture.runAsync(() -> {
      System.out.println("Polling in thread - " + Thread.currentThread().getName());
      while (blockingQueue.size() > 0) {
    
        AbortableCountDownLatch latch = blockingQueue.poll();
        latch.countDown();
      }
    }), (i, j) -> null);
    

    Both sleep and latchdown happens in different threads.

    Sleeping in thread - ForkJoinPool.commonPool-worker-19
    Polling in thread - ForkJoinPool.commonPool-worker-5
    Sleeping in thread - ForkJoinPool.commonPool-worker-19
    

    CompletionStages implements producer-consumer with the help of two stages chained using Async API and passing the executor with blocking queue. I think that should be the best fit for your use case.