我有线程将一些内容写入套接字然后开始等待响应。该线程需要在给定时间内检索响应,例如100毫秒。 我的想法是创建读取器线程,该线程将从套接字读取并在阻塞队列中存储响应。当读者完成工作并将对象放入队列时,第一个线程就会等待。如果读者在一段时间内做到了一切正常,如果读者不是我想抛出异常而且也没关系。问题是,当我在TimeOutException之后,由于超时而没有从队列中取出的对象仍然存在,甚至可能只是准备插入队列。我只想要下一个对象。我该如何跳过此消息?或者可能有更好的方法解决这个问题?
此外,连接保持活动状态,因此套接字超时不合适。
答案 0 :(得分:1)
我会将BlockingQueue
子类化为覆盖poll()
和offer()
方法,这些方法只会调用super.poll()
和super.offer()
。它将在提供新项目时添加时间戳,并在轮询时丢弃队列中已经存在的任何项目。类似的东西:
public class TimedItemBlockingQueue<T> extends ArrayBlockingQueue<TimedItem<T>> {
private class TimedItem<T> {
T data;
long timestamp;
TimedItem<T>(T data) {
this.data = data;
this.timeStamp = <get_tiemstamp>
}
T poll() {
TimedItem<T> item = super.poll();
if (isValid(item.timestamp)) {
return item.data;
}
/* Plus extra code to handle exceptions and other cases */
}
boolean offer(T data) {
TimedItem<T> item = new TimedItem<T>(data);
return super.offer(item);
}
您可能需要覆盖所有poll()
方法。
在这种情况下,第一个线程只调用poll()
,甚至不知道中间是否有这样的队列,或者有多少个对象已“过期”
答案 1 :(得分:0)
最好的方法是让发件人包含一个时间戳(或者如果不可能,读者包含一个时间戳)当您从队列中收到消息时,检查时间戳,如果没有足够的时间,则认为它已经定时out(或它会)
如果你需要对调用队列的代码透明,你可以创建一个丢弃旧消息的Queue子类。