Java 这是怎么回事;“集装箱设计模式”;打电话?

Java 这是怎么回事;“集装箱设计模式”;打电话?,java,multithreading,design-patterns,containers,readerwriterlock,Java,Multithreading,Design Patterns,Containers,Readerwriterlock,在创建我的应用程序时。架构我面临一个结构的需求,将在下面描述 我很确定,有一个众所周知的设计模式具有相同的功能,因为我认为我开发它的问题非常普遍 我自己编写了这个实现,但我总是尝试使用模式的“内置语言”实现,所以-请帮我命名这个构造 这种想法接近于读者-作者模式。我们有一个“容器”,可以在其中通过键()添加对象。我们还可以通过键获取这些对象,将其从容器中移除 因此,实现的类应该有两种方法: void putObject(Key key, Object object); Object getObj

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

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

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

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

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

void putObject(Key key, Object object);
Object getObject(Key key); // remove <Key,Object> from container.
void putObject(键、对象);
对象获取对象(键);//从容器中取出。
其次是最有趣的。 此容器应在多线程环境中工作,如下所示:

  • 如果调用get(key)时没有与key关联的对象 方法调用方线程应在此方法中等待对象 容器
  • 当另一个线程将调用putObject(键、对象对象) 方法,它应该检查是否有某个线程正等待 这个对象,如果它是-那么发出信号并唤醒 等待
  • 我认为这是一种常见的结构,它有“官方”名称吗

    此模式的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 {
    
        }
    
    专用静态接口黑盒{
    public void addObject(IdObject对象);
    public-IdObject-getObject(ObjectId-id);
    }
    私有静态类BlackOximpl实现BlackBox{
    private final Lock conditionLock=new ReentrantLock();
    私有最终地图保存对象;
    私人最终地图等待条件;
    公共黑名单(){
    this.savedObjects=新的ConcurrentHashMap(20);
    this.waitingConditions=新的ConcurrentHashMap(20);
    }
    @凌驾
    公共无效添加对象(IdObject对象){
    savedObjects.put(object.getId(),object);
    if(waitingConditions.containsKey(object.getId())){
    条件waitCondition=waitingConditions.get(object.getId());
    conditionLock.lock();
    waitCondition.signal();
    conditionLock.unlock();
    }
    }
    @凌驾
    公共IdObject getObject(ObjectId){
    if(savedObjects.containsKey(id)){
    返回savedObjects.get(id);
    }否则{
    conditionLock.lock();
    条件waitCondition=conditionLock.newCondition();
    waitingConditions.put(id,waitingcondition);
    waitCondition.waitunterrupty();
    conditionLock.unlock();
    返回savedObjects.get(id);
    }
    }
    }
    私有静态接口IdObject{
    public ObjectId getId();
    }
    私有静态类IdObjectImpl实现IdObject{
    受保护的最终对象id;
    公共IdObjectImpl(对象id){
    this.id=id;
    }
    @凌驾
    公共ObjectId getId(){
    返回id;
    }
    }
    私有静态接口ObjectId{
    }
    私有静态类objectimpl实现ObjectId{
    }
    
    我可能会使用

    ConcurrentMap<K,BlockingQue<V>>. 
    
    ConcurrentMap。
    
    使用映射的并发方法添加对。从队列中获取值。使用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));
        }
    }
    
    静态类多队列{
    //基础结构。
    最终ConcurrentMap队列=新ConcurrentHashMap();
    /**
    *将项目放入结构中。
    *
    *如果当前没有条目,将创建地图中的条目。
    *
    *然后将该值发布到队列中。
    */
    公共void put(kk,vv)抛出InterruptedException{
    //如果不在场,就做吧。
    确保代表性(k)、put(v);
    }
    /**
    *从结构中获取项目。
    *
    *如果当前没有条目,将创建地图中的条目。
    *
    *然后将从队列中获取该值。
    */
    public void get(K)抛出InterruptedException{
    //如果不在场,就去做,然后等待。
    确保代表性(k.take();
    }
    私有阻塞队列代表(K){
    //如果不在场,就做吧。
    返回队列.ComputeFabSent(k,v->new ArrayBlockingQueue(1));
    }
    }
    
    看看你的设计,告诉我你在描述什么

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

    几乎是并行的。它使用一组准备好使用的初始化对象。池的客户端将从池中请求一个对象,并对返回的对象执行操作


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

    实际上,您所说的是在多线程中具有棘手行为的某种映射(某种程度上,这种行为似乎类似于某种队列逻辑)。据我所知,在集合的任何Java实现中都没有这种开箱即用的行为。在任何情况下,您都必须修改库实现。您是在谈论BlockingQueue吗?@YaroslavRudykh我想它非常接近,但没有键对象关系。在队列中,我们按顺序读取对象,而不是按键。@YaroslavRudykh我说的是某种阻塞队列。BlockingQueue用于生产者-消费者模式,但我要谈的是另一件事。当我们使用阻塞队列时,我们只是发出这样的信号:“嘿,这个容器中有一个新元素。”每个人都可以得到它。但是我需要一个模式,它将为特定的服务员提供特定的对象。当我们调用get(Key)方法时,我们