java生产者消费者多线程基准测试。为什么会停止?

java生产者消费者多线程基准测试。为什么会停止?,java,multithreading,benchmarking,Java,Multithreading,Benchmarking,请帮我解决我的问题 我有针对服务器的java程序测试,类似于echo,一个基准测试工具 要简化: 我从不同数量的线程向服务器发送100条消息(例如,模拟真实世界的生产者,从10个客户端或1个客户端发送消息并不重要),并接收响应 我对消费者也有同样的情况(comsumer=thread)。生产者和消费者生成事件(从…接收的消息从…发送的消息等) 我的main使用onMessage()实现MyEventListener,并计算所有内容 我的问题是,我无法接收所有100条消息并计数它们,因为程序在消息

请帮我解决我的问题

我有针对服务器的java程序测试,类似于echo,一个基准测试工具

要简化:

我从不同数量的线程向服务器发送100条消息(例如,模拟真实世界的生产者,从10个客户端或1个客户端发送消息并不重要),并接收响应

我对消费者也有同样的情况(comsumer=thread)。生产者和消费者生成事件(从…接收的消息从…发送的消息等)

我的main使用onMessage()实现MyEventListener,并计算所有内容

我的问题是,我无法接收所有100条消息并计数它们,因为程序在消息发送后停止。我知道这很简单,但不知道如何解决它(

这是我的密码:

public static void main(String[] args) throws InterruptedException {
    Main m = new Main();
    m.init();
}
private int mesReceved=0;
public void init() throws InterruptedException {
    Sender s = new Sender(15,this);
    Resender r = new Resender(15,this);
    r.createThreads();
    r.startThreads();
    s.createThreads();
    s.startThreads();
    System.out.println(mesReceved);

}
public void onEvent(String string) {
    mesReceved++;
}

我认为这段代码没有问题

您是否可以尝试简化问题,例如减少线程,直到问题停止发生

在最简单的情况下,例如使用4个线程,在这种情况下

  • 拿一个线程堆栈
  • 使用调试或
  • 添加日志以诊断问题

    • 我认为这段代码没有问题

      您是否可以尝试简化问题,例如减少线程,直到问题停止发生

      在最简单的情况下,例如使用4个线程,在这种情况下

      • 拿一个线程堆栈
      • 使用调试或
      • 添加日志以诊断问题

      您是如何启动您的程序的?它可能会成功完成,然后关闭窗口。有几种方法可以解决这个问题


      我想到的一个想法是,你可以在主线程中尝试一个线程。sleep(time)(时间是你希望它以毫秒为单位等待的时间。)

      你是如何启动你的程序的?它可以成功完成,然后关闭窗口。有几种方法可以解决这个问题


      我想到的一个想法是,您可以在main中尝试一个Thread.sleep(time)(其中time是您希望它以毫秒为单位等待的时间)

      在离开
      main
      之前,您真的在等待线程完成吗?您应该使用
      Thread。在
      main
      末尾的所有创建线程上加入
      ,否则主线程将在不等待子线程完成的情况下退出。

      在离开之前,您真的在等待线程完成吗
      main
      ?您应该使用
      Thread。在
      main
      末尾的所有已创建线程上加入
      ,否则主线程将在不等待子线程完成的情况下退出。

      您的问题在于主线程在安装过程后终止,因此终止所有其他线程

      等待线程完成其工作的一种优雅方式是使用高级同步辅助工具,如

      在这种情况下,您可以像这样重写init代码:

      public void init() throws InterruptedException {
          ...
          producer = r.createThreads();
          r.startThreads();
          consumer = s.createThreads();
          s.startThreads();
          ...
          producer.getCountDownLatch().await();      // wait for all producers to finish
          consumer.getCountDownLatch().await();      // wait for all consumers to finish 
          // note: you could also encapsulate the latch and internally delegate the await
          // producer.await(); // nicer to read
      }
      
      在Sender和Receiver类上,创建并维护CountDownLatch:

      class Sender {
          final CountDownLatch sync;
          public Sender (int threadCount) {
              sync = new CountDownLatch(threadCount);
              ...
          }
          public CountDownLatch getCountDownLatch() {
              return sync;
          }
          // alternative
          public boolean await() {
              return sync.await();
          }
      } 
      
      创建线程时,将倒计时闩锁传递给每个可运行线程。 当它们完成工作时,您将减小闩锁:

      class MyRunnable implements Runnable {
          private final CountDownLatch latch;
          public MyRunnable(CountDownLatch latch) {
              this.latch = latch;
              ...
          } 
          public void run() {
              // DO STUFF
              latch.countDown();
          }
      }
      
      有了这个同步过程,您的程序只有在所有生产者和消费者都完成他们的工作时才会终止。 另外,
      await
      方法可以将超时作为参数,这样可以确保程序在某些边界内终止。 e、 g.让所有生产商工作,但只需等待消费者5分钟:

      public void init() {
          ...
          producer.getCountDownLatch().await();      // wait for all producers to finish
          boolean allFinished = consumer.getCountDownLatch().await(5, TimeUnit.MINUTES);      // wait 5 minutes for all consumers to finish.
          if (!allFinished) {
              // alert that not all consumers ended on time
          }
          ...
      }
      

      您的问题在于,主线程在安装过程之后终止,因此会终止所有其他线程

      等待线程完成其工作的一种优雅方式是使用高级同步辅助工具,如

      在这种情况下,您可以像这样重写init代码:

      public void init() throws InterruptedException {
          ...
          producer = r.createThreads();
          r.startThreads();
          consumer = s.createThreads();
          s.startThreads();
          ...
          producer.getCountDownLatch().await();      // wait for all producers to finish
          consumer.getCountDownLatch().await();      // wait for all consumers to finish 
          // note: you could also encapsulate the latch and internally delegate the await
          // producer.await(); // nicer to read
      }
      
      在Sender和Receiver类上,创建并维护CountDownLatch:

      class Sender {
          final CountDownLatch sync;
          public Sender (int threadCount) {
              sync = new CountDownLatch(threadCount);
              ...
          }
          public CountDownLatch getCountDownLatch() {
              return sync;
          }
          // alternative
          public boolean await() {
              return sync.await();
          }
      } 
      
      创建线程时,将倒计时闩锁传递给每个可运行线程。 当它们完成工作时,您将减小闩锁:

      class MyRunnable implements Runnable {
          private final CountDownLatch latch;
          public MyRunnable(CountDownLatch latch) {
              this.latch = latch;
              ...
          } 
          public void run() {
              // DO STUFF
              latch.countDown();
          }
      }
      
      有了这个同步过程,您的程序只有在所有生产者和消费者都完成他们的工作时才会终止。 另外,
      await
      方法可以将超时作为参数,这样可以确保程序在某些边界内终止。 e、 g.让所有生产商工作,但只需等待消费者5分钟:

      public void init() {
          ...
          producer.getCountDownLatch().await();      // wait for all producers to finish
          boolean allFinished = consumer.getCountDownLatch().await(5, TimeUnit.MINUTES);      // wait 5 minutes for all consumers to finish.
          if (!allFinished) {
              // alert that not all consumers ended on time
          }
          ...
      }
      

      问题是,当程序转到System.out.println(mesReceved)时;它打印0并结束。我没有收到所有响应。我希望,我是对的?无论如何,我现在将尝试稍微更改代码,并尝试,谢谢。我希望它打印0,因为您尚未收到任何消息。也就是说,您没有等待线程做任何事情,您使用线程是因为您不想等待它们完成。如果您的程序退出,可能您的线程是守护进程线程,这意味着您的程序也不会等待它们完成。如果我从main中的new thread启动s.createThreads();s.startThreads();则生成:newThread.join();它仍然可以正常工作,我做错了什么?您需要join()在您想要等待的线程上,而不是启动它们的线程上。一个更简单的解决方案是不让线程成为守护线程。是的,我知道,当我创建了可运行线程时,它只负责创建其他线程,当它完成时,线程结束了,所以我清楚地看到“结束”.我必须加入Direct workers,但不是这个。!问题是,当程序进入System.out.println(mesReceved)时;它打印0并结束。我没有收到所有响应。我希望,我是对的?无论如何,我现在将尝试稍微更改代码,并尝试,谢谢。我希望它打印0,因为您尚未收到任何消息。也就是说,您没有等待线程做任何事情,您使用线程是因为您不想等待它们完成。如果您的程序退出,可能您的线程是守护进程线程,这意味着您