请帮我解决我的问题。
我有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++;
}
答案 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
}
...
}