0

我试图避免让当前线程休眠,直到 ScheduledFuture 以 0 延迟执行。不幸的是,我找不到一个针对未来的钩子来通知可运行文件何时执行。有问题的未来包装了一个番石榴 cache.put(key,value) 操作。应在缓存使密钥到期之前调用可运行对象...本质上,我希望一个密钥永不过期。

    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();
    }

执行程序服务确实会立即运行代码,但启动线程存在滞后时间。这种滞后将是系统特定的,所以我想避免任意睡眠。

我正在使用 ScheduledThreadPoolExecutor 创建 ScheduledFuture,并且可以使用该类型的访问器(例如 isDone())获得我想要的行为。但是,这似乎也很hacky。是否有更简洁的实现可以提供休眠当前线程的行为而不使用 Executor 服务的副作用?

谢谢,罗宾

编辑:显示没有 Thread.sleep() 失败的测试

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

为了正常工作,应同步执行 put(key,value) 以允许立即执行 get(key) 操作。

4

1 回答 1

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();
于 2017-11-02T16:20:39.653 回答