首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java BlockingQueue

Java BlockingQueue
EN

Stack Overflow用户
提问于 2014-06-03 04:16:59
回答 2查看 175关注 0票数 1

我设置了一个最初的容量为3。但一些时间生产者是超越最初的容量。请参考输出。

问题更新:为了线程安全, ArrayBlockingQueue使用显式锁,但在代码中,我获得了sharedResource对象的监视器/隐式锁。

如何使System.out.println("Produce : "+d);成为同一个显式锁的一部分? /How,以实现所需的输出输出,打印具有相同BQ锁的BQ内部的输出?

声明

代码语言:javascript
复制
BlockingQueue<String> sharedResource = new ArrayBlockingQueue<String>(3);

生产者

代码语言:javascript
复制
Runnable r = new Runnable() {
    public void run() {
        for (int i = 1; i <= 2; i++) {
            try {

                String d = Thread.currentThread().getName() + "->" + i;
                synchronized (sharedResource) {
                    sharedResource.put(d);
                    System.out.println("Produce : " + d);
                }
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
};

Consumer

代码语言:javascript
复制
Thread consumer = new Thread(new Runnable() {
    public void run() {
        while (true) {

            try {
                System.out.println("C : " + sharedResource.take());
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
});

OutPut

代码语言:javascript
复制
***P1->1
P3->1
P5->1
P2->1***
C : P1->1
C : P3->1
P4->1
C : P5->1
P2->2
P5->2
C : P2->1
P3->2
C : P4->1
P1->2
C : P2->2
P4->2
C : P5->2
C : P3->2
C : P1->2
C : P4->2

更新:我如下所示调用生产者和消费者。

代码语言:javascript
复制
Thread producer1 = new Thread(r);
Thread producer2 = new Thread(r);
Thread producer3 = new Thread(r);
Thread producer4 = new Thread(r);
Thread producer5 = new Thread(r);

producer1.setName("P1");
producer2.setName("P2");
producer3.setName("P3");
producer4.setName("P4");
producer5.setName("P5");

producer1.start();
producer2.start();
producer3.start();
producer4.start();
producer5.start();

consumer.start();
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-03 06:46:22

如果你的问题是“第四个输出P2->1是奇怪的”,正如我在评论中描述的。

以下是我的回答:

BQ运行良好,但这是与BQ操作和System.out同步的问题。

如果希望输出正确,请使用以下块

代码语言:javascript
复制
sharedResource.put(d);
System.out.println("Produce : " + d);

应该是一个原子操作,可以是

代码语言:javascript
复制
System.out.println("C : " + sharedResource.take());

但是,由于puttake已经阻塞了线程,所以很难将System.out合并到puttake的锁中。

我不知道你打印这些信息的目的是什么。如果只是为了测试Java是否运行良好,我向您保证“是”。

如果你真的想要正确的输出,我建议你实现你自己的BQ并使System.out在锁内。

票数 1
EN

Stack Overflow用户

发布于 2014-06-03 05:11:20

在ArrayBlockingQueue#take()方法中,答案非常简单

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ArrayBlockingQueue.html#take()

它说,当您调用you时,“检索并移除该队列的头,必要时等待元素可用”。因此,它将队列大小减少了1,因此请考虑1。队列2中有4个元素。调用the () 3。队列大小将减少到3。

因此,在这种情况下,队列不会超过3的大小。您同时将值从队列中移除,这样队列大小就不会超过3,但是如果您用Thread.sleep(500)来减缓您的使用者,您将得到所需的输出。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24007043

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档