我应该有专门的线程来观看超时吗?

时间:2016-08-12 13:36:42

标签: java multithreading

现在我的程序中运行了两个线程。一个人不断尝试读取用户的输入,另一个人观察超时。如果用户在给定的时间内未发送任何输入,则会发生超时。这两个线程看起来像这样:

用户输入线程

TRectangle

超时线程

while(true){
    if(in.hasNextLine()){
        processLine(in.nextLine());
        timeLastRecieved = System.currentTimeMillis();
    }
}

截至目前,我将这些线程分开,但我可以将它们组合起来......

while(true){
    //Check for a timout
    if(timeLastRecieved+timeoutDuration <= System.currentTimeMillis())
        timeUserOut();

    else{
        //Sleep until it is possible for a timeout to occur
        Thread.sleep((timeLastSent+timeoutDuration) - System.currentTimeMillis());   
    }
}

但我真的不需要经常检查超时。所以我应该组合线程并经常检查超时,或者我应该有两个线程。我并不担心表现,因为我是正确的编码礼仪。如果它意味着超时持续时间长达15分钟。

编辑:只是想指出在我正在睡觉的两个线程的版本中,但在组合版本中我从不睡觉线程。这显然会导致检查超时的if语句运行得更多。

2 个答案:

答案 0 :(得分:0)

你需要有两个线程 - 一个等待通过InputStream / Reader进入的数据,另一个正在观察时间是否已经过了太长时间。使用1个线程执行此操作的唯一方法是在一段超时时间内休眠,然后定期轮询数据。但是这比使用专用于从InputStream / Reader读取的单独线程效率低。

您可能需要查看Timeout作为实现超时的通用选项

答案 1 :(得分:0)

总结一下我的评论:我认为不需要单独的线程来检查超时。

原因:

  • 您需要在它们之间共享timeLastRecieved之类的信息,这可能比想要的更复杂(例如,在某些情况下,AFAIK对long值的访问不是原子的)。
  • 根据您的描述,似乎轮询用户输入和超时(没有及时提供输入)密切相关,因此轮询线程也可以检查超时。这并不意味着它也必须处理超时,只是在某处报告或调用一些超时处理程序可能是更好的设计。
  • 更新timeLastRecieved更容易阅读和理解,并且在同一位置处理检查超时。
  • 由于没有线程间通信也不需要协调(没有需要通信的线程),因此它可能也更健壮。

检查超时的一些提示:

  • 您应该在更新timeLastReceived时计算超时阈值,然后再次检查当前时间,而不是在每次迭代中计算它。
  • 您可能希望在处理输入之前计算超时阈值,以便不依赖于处理时间。

最后,还有其他方法,例如使用java.util.Timer。在这里,您可以简单地安排在超时发生时执行的超时任务。然后,该任务将检查超时是否真的发生,如果不是,则返回。

要在发生超时之前处理新输入,您可以使用至少两种方法:

  • 取消当前超时任务,将其从计时器中删除并安排新计时。
  • 如果已经有计划的超时任务,则不要安排新的任务,而是等待当前的任务运行。然后当前的一个检查超时,如果没有发生,则为当前预期的超时安排一个新任务(或自身)(注意这需要一些线程间通信,所以在这里要小心)。