我试图在Java中使用Producer-Consumer模型中的许多线程,并且由于某种原因,它没有做它应该做的事情。
我有代码
List<Thread> consumers = new ArrayList<>();
for (int i = 0; i < noOfThreads; i++) {
Thread consumer = new Thread(new Runnable() {
String name = "Thread-" + UUID.randomUUID();
@Override
public void run() {
try {
pc.consume(name);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
consumers.add(consumer);
consumer.start();
consumer.join();
}
其中pc
是ProducerConsumer,其使用方法是
public void consume(String name) throws InterruptedException {
while (true) {
synchronized (this) {
while (subQueue.size() == 0) {
wait(2000);
}
Subscriber sub = subQueue.poll();
System.out.println(name);
uploadEndpointToPinpoint(sub);
notify();
}
}
}
所以,当我运行它时,我希望看到它打印出10个不同的UUID,表明有10个线程正在运行 - 但是没有发生。相反,我得到:
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
这意味着它只启动了其中一个线程。为什么for循环没有做我认为应该做的事情?
任何和所有帮助将不胜感激。
答案 0 :(得分:1)
调用Thread#join()阻塞当前线程,直到目标线程不再运行。在你的循环中,你实际上是在启动一个线程,然后等待它完成,这就是你只看到一个线程的原因。如果要等待所有线程完成,则需要在创建线程的循环外部移动join()调用。
List<Thread> consumers = new ArrayList<>();
for (int i = 0; i < noOfThreads; i++) {
Thread consumer = new Thread(new Runnable() {
String name = "Thread-" + UUID.randomUUID();
@Override
public void run() {
try {
pc.consume(name);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
consumers.add(consumer);
consumer.start();
}
for (Thread thread : consumers) {
thread.join();
}