【问题标题】:ArrayBlockingQueue exceeds given capacityArrayBlockingQueue 超出给定容量
【发布时间】:2012-10-23 22:49:11
【问题描述】:

我编写了解决有界生产者和消费者问题的程序。在构造 ArrayBlockingQueue 时,我定义了容量 100。我正在使用方法 take 和 put 内部线程。而且我注意到,有时我会看到 102 次 put ,它们之间有任何 take 。为什么会这样?

生产者运行方法:

public void run() {
    Object e = new Object();
    while(true) {
        try {
            queue.put(e);
        } catch (InterruptedException w) {
                System.out.println("Oj, nie wyszlo, nie bij");
        }
        System.out.println("Element added");

    }
}

消费者运行方式:

public void run() {
    while(true) {
        try {
            queue.take();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Element removed");
    }
}

uniq -c 文件的一部分,带有输出:

102 Element removed
102 Element added
102 Element removed
102 Element added
102 Element removed
102 Element added
102 Element removed
102 Element added
102 Element removed
102 Element added
102 Element removed
102 Element added
  2 Element removed
  2 Element added
102 Element removed
102 Element added

【问题讨论】:

    标签: java concurrency java.util.concurrent capacity


    【解决方案1】:

    我定义了容量 100。我正在使用方法 take 和 put 内部线程。而且我注意到,有时我会看到 102 次 put ,它们之间有任何 take 。为什么会这样?

    这很可能是您的输出中竞争条件的副产品,而不是暗示阻塞队列在队列中曾经有超过 100 个条目。一个线程可能会从队列中删除一些东西之后一个元素被放入队列但显示"removed"消息之前推杆可以显示"added"消息-和反之亦然。队列调用和System.out.println(...) 之间没有锁定,因此无法保证顺序。

    如果有任何问题,请打印出 queue.size() 以查看它是否超过 100。ArrayBlockingQueue 永远不会向您显示。

    【讨论】:

    • 我创建了容量 = 1 的 ArrayBlockingQueue,并且能够将任意数量的对象添加到队列中。
    • 呃。行。嗨@ValeriyK。你好吗?你调用了什么BlockingQueue 方法?如果是queue.add(...),那么第二次调用会引发“队列满时”异常,我敢打赌你有一个catch(Exception),它吸收并丢弃了它。如果是queue.put(...),那么它应该挂在第二个电话上,直到有人从队列中取出。今后,请提供更多信息和一些细节。
    • 嗨。是的你是对的。这是几个顺序 queue.put(..) 方法,仅用于测试。我以为他们一个接一个地工作。但是当我添加日志时,我看到队列大小总是等于 1。每个 put 方法调用都会等待,直到另一个方法从队列中取出一个元素。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-19
    • 2012-06-01
    • 2018-11-08
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    相关资源
    最近更新 更多