Java 阻塞 Q 测试停止执行

问题描述

我有以下用于学习目的的测试代码,我试图在其中运行一个生产者和一个消费者线程,在阻塞 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();
    }  
}