首页 文章

在 生产环境 者 - 消费者模型中关闭队列的最有效对象是什么?

提问于
浏览
0

在 生产环境 者 - 消费者模型中(一个生成项目的线程,将其置于阻塞队列中,另一个线程在无限循环中使用它们),建议通过发送导致循环中断的毒物对象来关闭线程 .

Afaik,这可以通过使用:

  • null (一般不鼓励, BlockingQueue 禁止)

  • 生产环境 者不会创造的值(需要额外的测试,可能会蒸发一些脑细胞)

  • 一个包装器类型,并将每个生成的值放在一个包含值作为唯一属性的类中,并设置为null以指示关闭(例如,Guava框架的 Optional )(需要为每个生成的项目分配昂贵的对象)

  • 添加到类中的额外属性用作项类型(使模型非常不灵活)

  • 生成器创建的类型的子类,仅用于中毒对象(不会消耗显着的空间,但是有缺点)

  • 中断线程不允许清除队列 .

我正在寻找任意队列项的类型安全解决方案 .

2 回答

  • 0

    好的,这就是我要做的:

    我将定义一个所有消息都需要实现的接口:

    public interface Message {
        public default boolean continueProcessing() {
            return true;
        }
    }
    

    然后是毒药枚举类:

    public enum Poison implements Message {
        INSTANCE;
    
        @Override
        public boolean continueProcessing() {
            return false;
        }
    }
    

    消费者代码如下所示:

    @Override
    public void run() {
        while (true) {
            Message msg = queue.take();
            if (!msg.continueProcessing()) {
                break;
            }
            doSomethingWith(msg);
        }
    }
    
  • 0

    你可以使用毒丸 . Value 无关紧要:

    制片人:

    class Producer{
        public static final ItemType POISON = new ItemType();
    
        // rest goes here
    }
    

    消费者:

    class Consumer{
        void run(){
             for(;;){
                  ItemType item = queue.take();
                  if( item == Producer.POISON ) // <- not checking value of item here!
                      break;
                  handleItem( item );
             }
        }
    }
    

    如果确保没有缓存 POISON ,这也适用于可以缓存的类似Integer的类型 .

    在不知道你的ItemType实际是什么的情况下,这是我可以向你推荐的最好的(恕我直言) .


    我想到的另一个想法是在Producer上引入一个字段,表示在清空队列后不再需要Item . 这意味着以某种方式对消费者代码中的空队列进行额外检查 . 这也意味着你不能阻塞空队列......在实现这个时要考虑很多 .

相关问题