问题描述
我有以下用于学习目的的测试代码,我试图在其中运行一个生产者和一个消费者线程,在阻塞 Q 上无休止地运行。
由于某种我无法理解的原因,输出如下:
Produced 3001
Q puts 3001
put: Q size = 1
Produced 3002
Q puts 3002
put: Q size = 2
Q takes 3001
take: Q size = 1
Consumed 3001
代码如下:
@Getter @Setter @NoArgsConstructor
public class MyBlockingQ {
public BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(5);
public Integer take() {
try {
Integer i = queue.take();
System.out.println("Q takes " + i);
System.out.println("take: Q size = " + queue.size());
return i;
} catch (InterruptedException e) {
e.printstacktrace();
return null;
}
}
public void put(Integer produce) {
try {
System.out.println("Q puts " + produce);
queue.put(produce);
System.out.println("put: Q size = " + queue.size());
} catch (InterruptedException e) {
e.printstacktrace();
}
}
}
public class MyProducer implements Runnable {
private final MyBlockingQ queue;
private Integer i = 3000;
public MyProducer(MyBlockingQ q) {
queue = q;
}
public void run() {
while (true) {
queue.put(produce());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printstacktrace();
}
}
}
Integer produce() {
i++;
System.out.println("Produced " + i);
return i;
}
}
public class MyConsumer implements Runnable {
private final MyBlockingQ queue;
public MyConsumer(MyBlockingQ q) {
queue = q;
}
public void run() {
while (true) {
consume(queue.take());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printstacktrace();
}
}
}
void consume(Integer x) {
System.out.println("Consumed " + x);
}
}
@Test
public void testBlockingQ(){
MyBlockingQ q = new MyBlockingQ();
MyProducer p1 = new MyProducer(q);
MyConsumer c1 = new MyConsumer(q);
new Thread(p1).start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printstacktrace();
}
new Thread(c1).start();
}
我不明白为什么代码在如上所示的最后一行输出之后停止执行? 我正在最新的 VSCode 上使用 JavaSE-15。
谢谢
解决方法
当你的测试方法结束时,线程被终止。如果您希望线程运行更长时间,则需要在测试方法结束时添加更多睡眠时间。
@Test
public void testBlockingQ(){
MyBlockingQ q = new MyBlockingQ();
MyProducer p1 = new MyProducer(q);
MyConsumer c1 = new MyConsumer(q);
new Thread(p1).start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(c1).start();
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}