我有一个定期操作,我想在定义的intervall中进行操作(粒度以秒为单位)。所以我使用了一个在请求的时间内休眠的线程,然后执行操作然后再次睡眠等等。
public class DiscoveryThread extends Thread
{
private int deviceDiscoveryIntervall = 1;
public void setDeviceDiscoveryIntervall(int seconds)
{
deviceDiscoveryIntervall = seconds;
}
@Override
public void run()
{
while(!isInterrupted())
{
//do there the action
try
{
sleep(deviceDiscoveryIntervall*1000);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
现在我想为定期行动设置一个新的intervall。如果intervall在10秒之前并且我在最后一次操作后5秒钟将其设置为1秒,我必须等待5秒直到下一个动作,但它应该立即执行此操作。
那我该怎么做呢?如果我使用interrupted()
方法,则sleep方法将抛出InterruptedException
,我可以立即执行操作。但是我必须为整个循环使用自己的标志,因为我不想退出线程。如何在sleep()
之后再次调用InterruptedException
方法,是否仍设置了中断标志?我能够再次中断sleep()
方法吗?如何使用interrupted()方法不停止线程,这不是一种错过它吗?
答案 0 :(得分:2)
线程应该在具有正确超时的对象上等待,当您希望线程提前唤醒时,在对象上调用notifyAll
。
你应该考虑使用ScheduledExecutorService
来做这样的事情,而不是试图自己动手。
答案 1 :(得分:1)
private final Runnable r = new Runnable() {
@Override
public void run() {
// ...
}
};
private final ScheduledExecutorService ses =
Executors.newSingleThreadScheduledExecutor();
ScheduledFuture<?> sf = ses.scheduleAtFixedRate(r, 0, 10, TimeUnit.SECONDS);
// change to 5 sec: cancel and reschedule
sf.cancel();
sf = ses.scheduleAtFixedRate(r, 0, 5, TimeUnit.SECONDS);