1

请帮我解决我的问题。

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

简化:

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

我和消费者有同样的情况(消费者=线程)。生产者和消费者生成事件(从...接收的消息...从...发送的消息等)

我的主要实现 MyEvenListener,带有 onMessage() 并计算所有内容。

我的问题是我无法收到所有 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 回答 4

1

您是否真的在等待线程完成后再离开main?您应该Thread.join在结束时使用所有创建的线程main,否则主线程将退出而不等待子线程完成。

于 2012-06-14T11:37:53.173 回答
1

我在这段代码中没有看到问题。

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

在最简单的情况下,例如有 4 个线程,就会发生这种情况

  • 取一个线程堆栈,
  • 使用调试或
  • 添加日志记录以诊断问题。
于 2012-06-14T07:53:13.297 回答
0

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

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

于 2012-06-14T08:04:31.140 回答
-1

您的问题在于主线程在设置过程之后终止,因此终止了所有其他线程。

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

在这种情况下,您可以像这样重写您的初始化代码:

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();
    }
} 

创建线程时,将 countDownLatch 传递给每个可运行对象。当它们完成工作时,您减少锁存器:

class MyRunnable implements Runnable {
    private final CountDownLatch latch;
    public MyRunnable(CountDownLatch latch) {
        this.latch = latch;
        ...
    } 
    public void run() {
        // DO STUFF
        latch.countDown();
    }
}

有了这个同步过程,你的程序只会在所有生产者和消费者都完成工作后终止。此外。该await方法可以将超时作为参数,以便您可以确保程序在某些边界内终止。例如,让所有生产者工作,但只为消费者等待 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
    }
    ...
}
于 2012-06-14T13:30:54.803 回答