执行器服务不起作用



我在使用 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;
        }
    }
}
}

我想知道为什么(消费者.java)案例 1 不起作用,但情况 2 很好

它打印笔记并且永不停止(此评论不好。忽略它ᅲᅲ)

我只是想知道,为什么案例 1 不是停止。

System.out.println 或 BlockingQueue 中是否有内容?

(Poducer.java也是。如果我在生产者中添加了 print i.java那么抛出中断异常)

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

请帮我;((我的英语不好,对不起)

这里的根本问题是,如果队列在queue.take()之前变为空,则使用者线程将阻塞,直到某些内容被添加到队列中。由于您在启动使用者之前执行所有添加到队列的操作,因此其中一个使用者是否会进入阻塞状态是运气问题。

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

如果您的用例涉及队列首先由Producer填充,然后运行Consumer线程,则应使用 poll() 而不是 take(),这将允许您检测元素用完的情况。

相关内容

  • 没有找到相关文章

最新更新