Какой лучший способ ждать в запланированном будущем с нулевой задержкой?

Я пытаюсь избежать сна текущего потока, пока ScheduledFuture выполняется с задержкой 0. К сожалению, я не могу найти ловушку против будущего, которая сообщает, когда исполняемый файл исполняется. Рассматриваемое будущее оборачивает операцию guava cache.put (ключ, значение). Runnable должен быть вызван до того, как кеш истекает ключ... по сути, я хочу, чтобы один ключ никогда не истек.

    final Runnable refresh = new Runnable() {
        @Override
        public void run()
        {
            cache.put( key, value );
        }
    };

    // replace the token when 95% of the ttl has passed
    long refreshInterval = (long)( keyExpires * 1000 *
                                   0.5 );

    // execute the future task and then delay the current thread long enough for the
    // executor to process the runnable. 50 ms should be long enough.
    ScheduledFuture<?> future = scheduler.scheduleAtFixedRate( refresh,
                                                               0,
                                                               refreshInterval,
                                                               TimeUnit.MILLISECONDS );

   /// this is the code I'd like to avoid
   try {
        Thread.sleep( 50 );
    } catch( InterruptedException e1 ) {} catch( ExecutionException e ) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

Служба executor действительно запускает код сразу, но есть время для ускорения потока. Это отставание будет зависеть от конкретной системы, поэтому я хочу избежать произвольного сна.

Я использую ScheduledThreadPoolExecutor для создания ScheduledFuture, и я могу получить поведение, которое я хочу, используя аксессор этого типа, например isDone(). Тем не менее, это тоже кажется глупым. Есть ли более чистая реализация, которая предлагает поведение спящего текущего потока без использования побочного эффекта от службы Executor?

Спасибо робин

Изменить: показать тест, который не проходит без Thread.sleep()

    cache.putNonExpiring( "key", "value" );
    Assert.assertNotNull( "Immediate get should have value", cache.get( "key" ) );

Чтобы работать правильно, пут (ключ, значение) должен выполняться синхронно, чтобы позволить немедленную операцию получения (ключ).

1 ответ

Решение

Возможно, вы могли бы использовать семафор или другой тип синхронизации, который блокируется текущим потоком до тех пор, пока исполняемый файл обновления не освободит семафор

// A semaphore initialized with no permits
final Semaphore runnableExecuting = new Sempahore(0);

final Runnable refresh = new Runnable()
{
    @Override
    public void run()
    {
        // Release one permit.  This should unblock the thread
        // scheduled this task.  After the initial releasing
        // the semaphore is essentially unneeded
        runnableExecuting.release();

        // Your code
    }
}

// After executor scheduling

// Attempt to acquire a permit, which the semphore initially has none.
// This will block until a permit becomes available
runnableExecuting.acquire();
Другие вопросы по тегам