消费者生产者错误中的意外输出
Unexpected output in Consumer Producer error
我得到了一个代码,我正在尝试 运行 它给出了意外的输出。
代码:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ProducerConsumerBlockingQueue {
public static void main(String[] args) {
Buffer buffer = new Buffer();
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(new ProdBlock(buffer));
executor.execute(new ConsBlock(buffer));
executor.shutdown();
}
}
class ProdBlock implements Runnable{
Buffer buffer;
public ProdBlock(Buffer buffer) {
this.buffer = buffer;
}
public void run() {
for(int i = 1; i <= 10; i++){
buffer.put(i);
}
}
}
class ConsBlock implements Runnable{
Buffer buffer;
ConsBlock(Buffer buffer){
this.buffer = buffer;
}
public void run() {
for(int i = 1; i <= 10; i++){
buffer.get();
}
}
}
class Buffer{
int i;
BlockingQueue<Integer> sharedObject = new ArrayBlockingQueue<Integer>(1);
public void get(){
try {
System.out.println("Getting - " + sharedObject.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void put(int i){
this.i = i;
try {
sharedObject.put(i);
System.out.println("Putting - " + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出:
Putting - 1
Putting - 2
Getting - 1
Putting - 3
Getting - 2
Getting - 3
Putting - 4
Putting - 5
Getting - 4
Getting - 5
Putting - 6
Getting - 6
Putting - 7
Putting - 8
Getting - 7
Getting - 8
Putting - 9
Putting - 10
Getting - 9
Getting - 10
预期输出:
Putting - 1
Getting - 1
Putting - 2
Getting - 2
Putting - 3
Getting - 3
Putting - 4
Getting - 4
Putting - 5
Getting - 5
Putting - 6
Getting - 6
Putting - 7
Getting - 7
Putting - 8
Getting - 8
Putting - 9
Getting - 9
Putting - 10
Getting - 10
正如预期的那样,阻塞队列一次应该只取 1 个值,它是如何存储多个值的?
它没有存储多个值。只是一旦 take() 方法已经返回,生产者可以在其他线程打印取值之前向队列添加一个值并打印它:
- 生产者线程:调用 put(1) - 队列有 1 个元素
- 生产者线程:打印"Putting 1" - 队列有 1 个元素
- 消费者线程:调用 take() - 队列为空
- 生产者线程:调用 put(2) - 队列有 1 个元素
- 生产者线程:打印"Putting 2" - 队列有 1 个元素
- 消费者线程:将字符串"Getting - "与第3步得到的整数1拼接,打印结果——队列有1个元素
我得到了一个代码,我正在尝试 运行 它给出了意外的输出。
代码:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ProducerConsumerBlockingQueue {
public static void main(String[] args) {
Buffer buffer = new Buffer();
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(new ProdBlock(buffer));
executor.execute(new ConsBlock(buffer));
executor.shutdown();
}
}
class ProdBlock implements Runnable{
Buffer buffer;
public ProdBlock(Buffer buffer) {
this.buffer = buffer;
}
public void run() {
for(int i = 1; i <= 10; i++){
buffer.put(i);
}
}
}
class ConsBlock implements Runnable{
Buffer buffer;
ConsBlock(Buffer buffer){
this.buffer = buffer;
}
public void run() {
for(int i = 1; i <= 10; i++){
buffer.get();
}
}
}
class Buffer{
int i;
BlockingQueue<Integer> sharedObject = new ArrayBlockingQueue<Integer>(1);
public void get(){
try {
System.out.println("Getting - " + sharedObject.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void put(int i){
this.i = i;
try {
sharedObject.put(i);
System.out.println("Putting - " + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出:
Putting - 1
Putting - 2
Getting - 1
Putting - 3
Getting - 2
Getting - 3
Putting - 4
Putting - 5
Getting - 4
Getting - 5
Putting - 6
Getting - 6
Putting - 7
Putting - 8
Getting - 7
Getting - 8
Putting - 9
Putting - 10
Getting - 9
Getting - 10
预期输出:
Putting - 1
Getting - 1
Putting - 2
Getting - 2
Putting - 3
Getting - 3
Putting - 4
Getting - 4
Putting - 5
Getting - 5
Putting - 6
Getting - 6
Putting - 7
Getting - 7
Putting - 8
Getting - 8
Putting - 9
Getting - 9
Putting - 10
Getting - 10
正如预期的那样,阻塞队列一次应该只取 1 个值,它是如何存储多个值的?
它没有存储多个值。只是一旦 take() 方法已经返回,生产者可以在其他线程打印取值之前向队列添加一个值并打印它:
- 生产者线程:调用 put(1) - 队列有 1 个元素
- 生产者线程:打印"Putting 1" - 队列有 1 个元素
- 消费者线程:调用 take() - 队列为空
- 生产者线程:调用 put(2) - 队列有 1 个元素
- 生产者线程:打印"Putting 2" - 队列有 1 个元素
- 消费者线程:将字符串"Getting - "与第3步得到的整数1拼接,打印结果——队列有1个元素