这个"容器设计模式"叫什么名字?

时间:2016-03-25 15:39:22

标签: java multithreading design-patterns containers readerwriterlock

创建我的应用时。架构我面对一个结构的需求,将在下面描述。

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

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

这个想法接近读者 - 作家模式。我们有一个"容器"我们可以通过key()添加对象。而且我们也可以通过键获取此对象,将其从容器中删除。

因此,实现的类应该有两个方法:

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)时 它应该检查是否有一些等待的线程 这个对象,如果是 - 然后发出信号并唤醒那个线程 等待。
  3. 我认为它是共同的结构,它是否具有&#34;官方&#34;名称?

    我对此模式的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 {
    
        }
    

2 个答案:

答案 0 :(得分: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));
    }
}

答案 1 :(得分:1)

看着你的设计,对我来说你在说什么

  

我们有一个&#34;容器&#34;我们可以通过key()添加对象。而且我们也可以通过键获取此对象,将其从容器中删除。   此容器应在多线程环境中工作

接近并发Object pool。它使用一组准备好使用的初始化对象。池的客户端将从池中请求对象并对返回的对象执行操作。

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