gpt4 book ai didi

java - ExecutorService 不起作用

转载 作者:行者123 更新时间:2023-12-01 10:14:57 24 4
gpt4 key购买 nike

我在使用 Executorservice 时遇到问题

我实现了消费者-生产者模式

主要

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {

public static void main(String[] args) {

BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(10000);

Thread producer = new Thread(new Producer(queue));
ExecutorService executorService = Executors.newFixedThreadPool(3);

Runnable consumer1 = new Consumer(queue);
Runnable consumer2 = new Consumer(queue);
Runnable consumer3 = new Consumer(queue);

producer.start();
executorService.submit(consumer1);
executorService.submit(consumer2);
executorService.submit(consumer3);

executorService.shutdown();


}
}

制作人

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Producer implements Runnable{
public BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(10000);

public Producer(BlockingQueue<Integer> queue) {
this.queue = queue;
}

public synchronized void run() {

for (int i=0; i<100; ++i) {
try {
//System.out.println("i = " + i);
queue.put(i);
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
}

消费者

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Consumer implements Runnable {

public BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(10000);

public Consumer(BlockingQueue<Integer> queue) {
this.queue = queue;
}

public void run() {
while (true) {
try {
//queue.take(); // case 1
System.out.println(Thread.currentThread().getName() + " Consumer : " + queue.take()); // case 2

} catch (InterruptedException e) {
System.out.println(e);
}

if (queue.isEmpty()) {
break;
}
}

}
}

我想知道为什么 (Consumer.java) 情况 1 不起作用,但情况 2 没问题

它打印注释并且永不停止(这个评论不好。忽略它ㅠㅠ)

我只是想知道,为什么情况 1 不是停止。

System.out.println或BlockingQueue中有什么东西吗?

(Poducer.java也是如此。如果我在Producer.java中添加了print i,则会抛出InterruptedException)

可能是我不太了解java和线程。

请帮助我;((我的英语不好,抱歉)

最佳答案

这里的根本问题是,如果队列在 queue.take() 之前变空,消费者线程将阻塞,直到有东西添加到队列中。由于您在启动消费者之前将所有内容添加到队列中,因此其中一个消费者是否会进入阻塞状态取决于运气。

情况 2(使用控制台输出)似乎减慢了速度,以至于没有线程进入此状态。如果情况 1 处理速度太快,至少有一个线程发现自己被阻塞。当我运行你的代码时,我发现线程 3 被阻塞,这意味着线程 1 和 2 可能在线程 3 有机会启动之前消耗了队列中的所有条目。

如果您的用例涉及队列首先由 Producer 填充,然后运行 ​​Consumer 线程,则应使用 poll() take() 可以让您检测元素耗尽的情况。

关于java - ExecutorService 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35954584/

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