3

在创建我的应用程序时。我需要一种结构,这将在下面描述。

我很确定,有一个众所周知的设计模式具有相同的功能,因为我认为我开发它的问题非常普遍。

我编写了自己的实现,但我总是尝试使用模式的“内置语言”实现,所以 - 请帮我命名这个结构。

这个想法接近于读写模式。我们有一个“容器”,我们可以在其中通过键 () 添加对象。我们也可以通过键获取这些对象,将其从容器中移除。

所以,实现的类应该有两个方法:

void putObject(Key key, Object object);
Object getObject(Key key); // remove <Key,Object> from container.

接下来是最有趣的。 该容器应在多线程环境中工作,如下所示

  1. 如果没有与 key 关联的对象,则在调用 get(Key key) 方法时,调用者线程应等待此容器中的对象。
  2. 当另一个线程调用 putObject(Key key, Object object) 方法时,它应该检查是否有一些线程正在等待这个对象,如果是 - 然后发出信号并唤醒等待的线程。

我认为它是常见的结构,它有“官方”名称吗?

我对这种模式的 Java 实现:

private static interface BlackBox {

        public void addObject(IdObject object);

        public IdObject getObject(ObjectId id);

    }

    private static class BlackBoxImpl implements BlackBox {

        private final Lock conditionLock = new ReentrantLock();
        private final Map<ObjectId, IdObject> savedObjects;
        private final Map<ObjectId, Condition> waitingConditions;

        public BlackBoxImpl() {
            this.savedObjects = new ConcurrentHashMap<ObjectId, IdObject>(20);
            this.waitingConditions = new ConcurrentHashMap<ObjectId, Condition>(20);
        }

        @Override
        public void addObject(IdObject object) {
            savedObjects.put(object.getId(), object);
            if (waitingConditions.containsKey(object.getId())) {
                Condition waitCondition = waitingConditions.get(object.getId());
                conditionLock.lock();
                waitCondition.signal();
                conditionLock.unlock();
            }
        }

        @Override
        public IdObject getObject(ObjectId id) {
            if (savedObjects.containsKey(id)) {
                return savedObjects.get(id);
            } else {
                conditionLock.lock();
                Condition waitCondition = conditionLock.newCondition();
                waitingConditions.put(id, waitCondition);
                waitCondition.awaitUninterruptibly();
                conditionLock.unlock();
                return savedObjects.get(id);
            }
        }

    }

    private static interface IdObject {

        public ObjectId getId();

    }

    private static class IdObjectImpl implements IdObject {

        protected final ObjectId id;

        public IdObjectImpl(ObjectId id) {
            this.id = id;
        }

        @Override
        public ObjectId getId() {
            return id;
        }

    }

    private static interface ObjectId {

    }

    private static class ObjectIdImpl implements ObjectId {

    }
4

2 回答 2

2

我可能会使用类似的东西

ConcurrentMap<K,BlockingQue<V>>. 

使用 Map 的并发方法来添加对。从您的队列中获取价值。使用 ArrayBlockingQue(1)。

可能是这样的:

static class MultiQueue<K, V> {

    // The base structure.
    final ConcurrentMap<K, BlockingQueue<V>> queues = new ConcurrentHashMap<>();

    /**
     * Put an item in the structure.
     *
     * The entry in the map will be created if no entry is currently there.
     *
     * The value will then be posted to the queue.
     */
    public void put(K k, V v) throws InterruptedException {
        // Make it if not present.
        ensurePresence(k).put(v);
    }

    /**
     * Get an item from the structure.
     *
     * The entry in the map will be created if no entry is currently there.
     *
     * The value will then be taken from the queue.
     */
    public void get(K k) throws InterruptedException {
        // Make it if not present - and wait for it.
        ensurePresence(k).take();
    }

    private BlockingQueue<V> ensurePresence(K k) {
        // Make it if not present.
        return queues.computeIfAbsent(k, v -> new ArrayBlockingQueue(1));
    }
}
于 2016-03-27T18:57:05.030 回答
1

看着你的设计,对我来说你所描述的

我们有一个“容器”,我们可以在其中通过键 () 添加对象。我们也可以通过键获取这些对象,将其从容器中删除。这个容器应该在多线程环境中工作

接近并发对象池。它使用一组随时可用的已初始化对象。池的客户端将从池中请求一个对象并对返回的对象执行操作。

我看到的唯一真正的区别是您根据自己的标准获取对象。

于 2016-03-27T19:30:47.507 回答