There is a stream "A" that accesses resource "B". Resource "B" can be used by another thread. In this case, the stream "A" should fall into standby mode. In the standby mode, there are two options: a) Resource "B" (namely resource "B") to access stream "A" and that having come out of expectation will begin to work with resource b) Flow "A" will wait some specified time and if this is exceeded time - stop their work (ie, existence).

To implement the idea of ​​option "b), it was decided to tie the timer to the flow and if the time was exceeded, the flow would simply exit the perpetual cycle. The problem arose in the fact that the timer has a feature: When you start the method that was laid for him, it turns on once before the countdown begins. And we need to make it so that when the timer starts, the timing goes, and only after the expiration of which would the method turn off the thread.

Is there a Timer class that will execute the code ONLY after some time has passed?

    1 answer 1

    Your task is the classic problem of the producer-consumer . You can solve it with the help of a queue, everything you need is in the standard library and almost nothing needs to be written by yourself. It will look like this:

    The class that creates some result (Resource B):

     private static class Producer<T> { private final BlockingQueue<T> queue; private Producer(BlockingQueue<T> queue) { this.queue = queue; } public void run(T element) { try { T result = somethingTooHard(element); queue.put(result); } catch (InterruptedException e) { e.printStackTrace(); } } private T somethingTooHard(T element) throws InterruptedException { TimeUnit.SECONDS.sleep(1); return element; } } 

    The class receiving the result (Stream A):

     private static class Consumer<T> { private final BlockingQueue<T> queue; private Consumer(BlockingQueue<T> queue) { this.queue = queue; } public void run() { try { T element = queue.poll(1, TimeUnit.SECONDS); if (element == null) System.out.println("вышли из ожидания по таймауту"); else System.out.println(String.format("получили элемент: %s", element)); } catch (InterruptedException e) { e.printStackTrace(); } } } 

    And a method to run them together:

     public static void main(String[] args) throws Exception { Executor executor = Executors.newFixedThreadPool(2); BlockingQueue<String> queue = new ArrayBlockingQueue<>(2); executor.execute(() -> new Producer<>(queue).run("hello world")); executor.execute(() -> new Consumer<>(queue).run()); }