簡體   English   中英

ExecutorService不起作用

[英]ExecutorService doens't work

我在使用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() ,這將使您檢測元素用盡的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM