具有超时的队列,用于删除未检索的对象

时间:2014-01-17 13:13:29

标签: java multithreading sockets concurrency timeout

我有线程将一些内容写入套接字然后开始等待响应。该线程需要在给定时间内检索响应,例如100毫秒。 我的想法是创建读取器线程,该线程将从套接字读取并在阻塞队列中存储响应。当读者完成工作并将对象放入队列时,第一个线程就会等待。如果读者在一段时间内做到了一切正常,如果读者不是我想抛出异常而且也没关系。问题是,当我在TimeOutException之后,由于超时而没有从队列中取出的对象仍然存在,甚至可能只是准备插入队列。我只想要下一个对象。我该如何跳过此消息?或者可能有更好的方法解决这个问题?

此外,连接保持活动状态,因此套接字超时不合适。

2 个答案:

答案 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子类。