我试图避免睡眠当前线程,直到ScheduledFuture以0延迟执行。不幸的是,我无法找到一个反对未来的钩子,通知runnable何时执行。有问题的未来包装了一个guava cache.put(key,value)操作。应该在缓存到期之前调用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();
}
执行程序服务确实立即运行代码,但是有一个延迟时间来启动一个线程。该延迟将是系统特定的,所以我想避免任意睡眠。
我正在使用ScheduledThreadPoolExecutor来创建ScheduledFuture,我可以使用该类型的访问器获取我想要的行为,例如isDone()。然而,这看起来也很糟糕。是否有一个更清晰的实现提供睡眠当前线程的行为而不使用Executor服务的副作用?
谢谢, 罗宾
编辑:显示没有Thread.sleep()
的测试失败 cache.putNonExpiring( "key", "value" );
Assert.assertNotNull( "Immediate get should have value", cache.get( "key" ) );
要正常工作,应同步执行put(键,值)以允许立即获取(键)操作。
答案 0 :(得分:1)
也许您可以使用当前线程阻塞的信号量或其他同步类型,直到刷新runnable释放信号量
// 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();