gpt4 book ai didi

Java生产者消费者停止消费者线程

转载 作者:行者123 更新时间:2023-12-03 12:45:46 25 4
gpt4 key购买 nike

我有这段代码,我想要一个停止消费者线程的好方法:

import java.util.ArrayDeque;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicBoolean;

public class Foo {
private final Queue<Object> queue;
private final AtomicBoolean doneReading;
private final int numberOfThreads = 4, N = 100;

public Foo() {
queue = new ArrayDeque<>();
doneReading = new AtomicBoolean(false);
}

public void execute() throws InterruptedException {
Thread[] threads = new Thread[numberOfThreads];
for (int i = 0; i < numberOfThreads; i++) {
threads[i] = new Thread(() -> {
try {
synchronized (queue) {
while (!doneReading.get() || !queue.isEmpty()) {
if (queue.isEmpty()) {
queue.wait();
if (!queue.isEmpty()) {
Object element = queue.remove();
// Do stuff
}
}
else {
Object element = queue.remove();
// Do stuff
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
});

threads[i].start();
}

for (int i = 0; i < N; i++) {
synchronized (queue) {
queue.add(new Object());
queue.notifyAll();
}
}

doneReading.set(true);
synchronized (queue) {
queue.notifyAll();
}

for (Thread thread : threads) {
thread.join();
}
}
}

基本上,当我读取了所有需要处理的数据后,我希望消费者线程停止。我试过 while(!doneReading.get()) 但这并不能保证队列中没有任何剩余的项目。我添加了 !queue.isEmpty(),但在这种情况下,一些线程会继续等待,即使它们不会收到任何通知。所以我设法再次调用 notifyAll() 。这似乎确实有效。我也想过在队列里加一个null,每当消费者读到一个null,就退出while。哪种方法更好,或者有什么更好的想法?

最佳答案

一种常用的方法是“毒丸”。在队列中放置一个特殊值,当读取时杀死消费者线程。这允许他们处理所有的值,并且在他们读取超过最终值并读取毒丸之前不会停止。

更多信息:https://java-design-patterns.com/patterns/poison-pill/

我也喜欢这些网站,它们通常有关于 Java 编程的深思熟虑的信息:

https://mkyong.com/java/java-blockingqueue-examples/

https://www.baeldung.com/java-blocking-queue

关于Java生产者消费者停止消费者线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65052819/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com