protected void waitAndSweep(String symbol) {
try {
long sweepTime = symbolInfo.getSweepTime(symbol);
long timeSinceLastSweep = System.currentTimeMillis() - sweepTime;
long waitTime = timeSinceLastSweep >= getInterval() ? 0 : getInterval() - timeSinceLastSweep;
logTradeEvent("waitAndSweep", symbol, "waittime: " + waitTime);
if (waitTime > 0){
Thread.sleep(waitTime);
}
callSweep(symbol);
}catch (InterruptedException e) {
Thread.currentThread().interrupt();
}catch (Exception e) {
logEvent(StrategyEntry.ERROR, "waitAndSweep", symbol,
"Exception caught...", e);
}
}
当它处于休眠状态(Thread.sleep)时,如何中断此线程以使其从waitandSweep方法中出来?
private void replace(){
// interrupt the thread;
// call waitandsweep again here;
waitandsweep(symbol)
答案 0 :(得分:4)
使用wait()
代替sleep()
,您可以通过notify()
唤醒该帖子,例如Difference between wait() and sleep()
答案 1 :(得分:1)
启动时保留对线程的引用,并在该引用上调用Thread#interrupt。如果线程处于休眠状态,则中断将导致sleep方法将其睡眠时间缩短并抛出InterruptedException;如果线程未休眠,则将设置中断标志。
我有一个在this answer中断线程的例子。
使用wait而不是sleep意味着你必须引入共享锁和条件变量。等待线程必须获取该锁,然后在循环中等待,检查条件变量。
条件变量和循环是必需的,原因如下:
1)线程可以在没有收到通知的情况下从等待返回("虚假唤醒"),
2)当线程没有锁定时发出通知,并且一旦线程设法重新获取该状态,就不会知道状态是否仍然与导致通知的状态相同锁定
在这种情况下,在这里使用中断似乎要少得多。
答案 2 :(得分:0)
您可以使用ArrayBlockingQueue并使用poll(long, java.util.concurrent.TimeUnit)。
然后你需要的只是醒来,将一些东西发布到队列中。
请不要尝试使用wait/notify
,因为有许多边缘情况会导致该机制失败。例如,如果在notify
超时之后发生wait
,则下一个等待是否会立即完成?使用BlockingQueue
可以在适当的时候排空它。