我设置了一个最初的容量为3。但一些时间生产者是超越最初的容量。请参考输出。
问题更新:为了线程安全, ArrayBlockingQueue使用显式锁,但在代码中,我获得了sharedResource对象的监视器/隐式锁。
如何使System.out.println("Produce : "+d);成为同一个显式锁的一部分? /How,以实现所需的输出输出,打印具有相同BQ锁的BQ内部的输出?
声明
BlockingQueue<String> sharedResource = new ArrayBlockingQueue<String>(3);生产者
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
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
***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更新:我如下所示调用生产者和消费者。
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();发布于 2014-06-03 06:46:22
如果你的问题是“第四个输出P2->1是奇怪的”,正如我在评论中描述的。
以下是我的回答:
BQ运行良好,但这是与BQ操作和System.out同步的问题。
如果希望输出正确,请使用以下块
sharedResource.put(d);
System.out.println("Produce : " + d);应该是一个原子操作,可以是
System.out.println("C : " + sharedResource.take());但是,由于put和take已经阻塞了线程,所以很难将System.out合并到put和take的锁中。
我不知道你打印这些信息的目的是什么。如果只是为了测试Java是否运行良好,我向您保证“是”。
如果你真的想要正确的输出,我建议你实现你自己的BQ并使System.out在锁内。
发布于 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)来减缓您的使用者,您将得到所需的输出。
https://stackoverflow.com/questions/24007043
复制相似问题