3
 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)
4

3 回答 3

4

使用wait()而不是sleep()允许您通过唤醒线程notify(),请参见例如Wait() 和 sleep() 之间的区别

于 2015-09-23T12:34:40.593 回答
1

启动时保留对线程的引用,并在该引用上调用Thread#interrupt。如果线程正在休眠,则中断将导致 sleep 方法缩短其休眠并抛出 InterruptedException;如果线程没有休眠,则设置中断标志。

我在这个答案中有一个中断线程的例子。

使用等待而不是睡眠意味着您必须引入共享锁和条件变量。等待线程必须获取该锁,然后在循环中等待,检查条件变量。

需要条件变量和循环有几个原因:

1)线程可以在没有收到通知的情况下从等待中返回(“虚假唤醒”),并且

2) 通知是在线程没有锁时发出的,一旦线程设法重新获得锁,状态是否仍会与导致通知的状态相同,这是无法确定的

在这种情况下,在这里使用中断似乎少了很多麻烦。

于 2015-09-23T12:39:24.180 回答
0

您可以使用ArrayBlockingQueue并使用poll(long, java.util.concurrent.TimeUnit)

然后,您需要做的就是唤醒胎面,在队列中发布一些东西。

请不要尝试使用wait/notify,因为该机制失败的边缘情况很多。例如,如果 anotify发生在wait超时之后,下一个等待会立即结束吗?使用 aBlockingQueue可以让您在适当的时候排出它。

于 2015-09-23T13:07:22.913 回答