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

时间:2012-06-14 07:42:55

标签: java multithreading benchmarking

请帮我解决我的问题。

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

简化:

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

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

我的主要实现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 个答案:

答案 0 :(得分:1)

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

您可以尝试简化问题,例如在问题停止发生之前减少线程。

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

  • 采取线程堆栈,
  • 使用调试或
  • 添加日志以诊断问题。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

你是如何推出你的计划的?它可以成功完成然后关闭窗口。有几种方法。

想到的一个想法是你可以在你的主要尝试Thread.sleep(时间)。 (时间是你希望它在几毫秒内等待的时间。)

答案 3 :(得分:-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传递给每个runnable。 当它们完成工作时,你减少了闩锁:

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
    }
    ...
}