Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我的ArrayBlockingQueue在放入列表后会导致一个空队列?_Java_Multithreading - Fatal编程技术网

Java 为什么我的ArrayBlockingQueue在放入列表后会导致一个空队列?

Java 为什么我的ArrayBlockingQueue在放入列表后会导致一个空队列?,java,multithreading,Java,Multithreading,这是我第一次问有关StackOverflow的问题。我的问题如下: 我有一个生产者和消费者阶层。在Producer类中,我逐行读取文件,并将这些文本行放入字符串列表中。当列表的行数为x时。此列表将添加到ArrayBlockingQueue。我有一个在主线程中启动的生产者线程。除此之外,我还启动了几个消费者线程。使用者线程从队列中获取一个项目,该项目应该是一个列表,并遍历该行列表以查找特定单词。当找到该单词时,它会增加一个count变量 结果是,当消费者从队列中取出一个项目时,它说它是空的。我不明

这是我第一次问有关StackOverflow的问题。我的问题如下:

我有一个生产者和消费者阶层。在Producer类中,我逐行读取文件,并将这些文本行放入字符串列表中。当列表的行数为x时。此列表将添加到ArrayBlockingQueue。我有一个在主线程中启动的生产者线程。除此之外,我还启动了几个消费者线程。使用者线程从队列中获取一个项目,该项目应该是一个列表,并遍历该行列表以查找特定单词。当找到该单词时,它会增加一个count变量

结果是,当消费者从队列中取出一个项目时,它说它是空的。我不明白为什么,因为我的制作人肯定应该把它添加到队列中

我的代码如下所示:

消费者类别:

public static class Consumer implements Callable<Integer> {

    int count = 0;

    @Override
    public Integer call() throws Exception {
        List<String> list = new ArrayList<>();
        list = arrayBlockingQueueInput.take();
        do {
            if (!list.isEmpty()){
                for (int i = 0; i < arrayBlockingQueueInput.take().size(); i++) {
                    for (String element : list.get(i).split(" ")) {
                        if (element.equalsIgnoreCase(findWord)) {
                            count++;
                        }
                    }
                }
            } else {
                arrayBlockingQueueInput.put(list);
            }
        } while (list.get(0) != "HALT");
        return count;
    }
}
public static class Consumer implements Callable<Integer> {

    int count = 0;

    @Override
    public Integer call() throws Exception {
        List<String> list = new ArrayList<>();
        do {
            list = arrayBlockingQueueInput.take();
            if (!list.get(0).equals(HALT)){
                for (int i = 0; i < list.size(); i++) {
                    for (String element : list.get(i).split(" ")) {
                        if (element.equalsIgnoreCase(findWord)) {
                            count++;
                        }
                    }
                }
            } else {
                arrayBlockingQueueInput.put(list);
            }
        } while (!list.get(0).equals(HALT));
        return count;
    }
}
公共静态类使用者实现可调用{
整数计数=0;
@凌驾
公共整数调用()引发异常{
列表=新的ArrayList();
list=arrayBlockingQueueInput.take();
做{
如果(!list.isEmpty()){
对于(int i=0;i
制片人级别:

public static class Producer implements Runnable {

    @Override
    public void run() {
        try {
            FileReader file = new FileReader("src/testText.txt");
            BufferedReader br = new BufferedReader(file);

            while ((textLine = br.readLine()) != null) {

                if (textLine.isEmpty()) {
                    continue;
                }

                /* Remove punctuation from the text, except of punctuation that is useful for certain words.
                * Examples of these words are don't or re-enter */
                textLine = textLine.replaceAll("[[\\W]&&[^']&&[^-]]", " ");

                /* Replace all double whitespaces with single whitespaces.
                * We will split the text on these whitespaces later */
                textLine = textLine.replaceAll("\\s\\s+", " ");

                textLine = textLine.replaceAll("\\n", "").replaceAll("\\r", "");

                if (results.isEmpty()) {
                    results.add(textLine);
                    continue;
                }
                if (results.size() <= SIZE) {
                    results.add(textLine);
                    if (results.size() == SIZE) {
                        if (arrayBlockingQueueInput.size() == 14){
                            List<String> list = new ArrayList<String>();
                            list.add(HALT);
                            arrayBlockingQueueInput.put(list);
                        } else{
                            arrayBlockingQueueInput.put(results);
                            results.clear();
                        }
                    }
                }
            }
            /* Count the remaining words in the list
             *  (last lines of the file do perhaps not fill up until the given SIZE, therefore need to be counted here)
             *  Fill the list with empty items if the size of the list does not match with the given SIZE */
            while (results.size() != SIZE) {
                results.add("");
            }
            arrayBlockingQueueInput.put(results);
            List<String> list = new ArrayList<String>();
            list.add(HALT);
            arrayBlockingQueueInput.put(list);
            results.clear();
        } catch (InterruptedException e) {
            producerIsRunning = false;
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
公共静态类生成器实现可运行{
@凌驾
公开募捐{
试一试{
FileReader file=newfilereader(“src/testText.txt”);
BufferedReader br=新的BufferedReader(文件);
而((textLine=br.readLine())!=null){
if(textLine.isEmpty()){
继续;
}
/*从文本中删除标点符号,但对某些单词有用的标点符号除外。
*这些单词的示例是“不”或“重新输入”*/
textLine=textLine.replaceAll(“[[\\W]&&&&[^']&&[^-]]”,“”);
/*将所有双空格替换为单空格。
*稍后我们将在这些空白处拆分文本*/
textLine=textLine.replaceAll(“\\s\\s+”,”);
textLine=textLine.replaceAll(“\\n”和“).replaceAll(“\\r”和“);
if(results.isEmpty()){
结果。添加(文本行);
继续;
}

如果(results.size()将列表添加到队列并清除它:

arrayBlockingQueueInput.put(results);
results.clear();
您需要执行以下操作才能将列表副本添加到队列中,以便
clear()
不会清除队列中的列表:

arrayBlockingQueueInput.put(new ArrayList<String>(results));
results.clear();
arrayBlockingQueueInput.put(新的ArrayList(结果));
结果:清晰();

在老师的帮助下,他帮我们找到了问题。有两个错误。一个是在producer类中。我有代码在主while循环中发出producer停止的信号。这不应该发生

除此之外,我在Consumer类中执行的.take()应该在do While循环中执行do While之前

正确的代码如下所示:

消费者类别:

public static class Consumer implements Callable<Integer> {

    int count = 0;

    @Override
    public Integer call() throws Exception {
        List<String> list = new ArrayList<>();
        list = arrayBlockingQueueInput.take();
        do {
            if (!list.isEmpty()){
                for (int i = 0; i < arrayBlockingQueueInput.take().size(); i++) {
                    for (String element : list.get(i).split(" ")) {
                        if (element.equalsIgnoreCase(findWord)) {
                            count++;
                        }
                    }
                }
            } else {
                arrayBlockingQueueInput.put(list);
            }
        } while (list.get(0) != "HALT");
        return count;
    }
}
public static class Consumer implements Callable<Integer> {

    int count = 0;

    @Override
    public Integer call() throws Exception {
        List<String> list = new ArrayList<>();
        do {
            list = arrayBlockingQueueInput.take();
            if (!list.get(0).equals(HALT)){
                for (int i = 0; i < list.size(); i++) {
                    for (String element : list.get(i).split(" ")) {
                        if (element.equalsIgnoreCase(findWord)) {
                            count++;
                        }
                    }
                }
            } else {
                arrayBlockingQueueInput.put(list);
            }
        } while (!list.get(0).equals(HALT));
        return count;
    }
}
公共静态类使用者实现可调用{
整数计数=0;
@凌驾
公共整数调用()引发异常{
列表=新的ArrayList();
做{
list=arrayBlockingQueueInput.take();
如果(!list.get(0).equals(HALT)){
对于(int i=0;i
制片人级别:

public static class Producer implements Runnable {

    @Override
    public void run() {
        try {
            FileReader file = new FileReader("src/testText.txt");
            BufferedReader br = new BufferedReader(file);

            while ((textLine = br.readLine()) != null) {

                if (textLine.isEmpty()) {
                    continue;
                }

                /* Remove punctuation from the text, except of punctuation that is useful for certain words.
                * Examples of these words are don't or re-enter */
                textLine = textLine.replaceAll("[[\\W]&&[^']&&[^-]]", " ");

                /* Replace all double whitespaces with single whitespaces.
                * We will split the text on these whitespaces later */
                textLine = textLine.replaceAll("\\s\\s+", " ");

                textLine = textLine.replaceAll("\\n", "").replaceAll("\\r", "");

                if (results.isEmpty()) {
                    results.add(textLine);
                    continue;
                }
                if (results.size() <= SIZE) {
                    results.add(textLine);
                    if (results.size() == SIZE) {
                        arrayBlockingQueueInput.put(new ArrayList<String>(results));
                        results.clear();
                    }
                }
            }
            /* Count the remaining words in the list
             *  (last lines of the file do perhaps not fill up until the given SIZE, therefore need to be counted here)
             *  Fill the list with empty items if the size of the list does not match with the given SIZE */
            while (results.size() != SIZE) {
                results.add("");
            }
            arrayBlockingQueueInput.put(new ArrayList<String>(results));
            List<String> list = new ArrayList<String>();
            list.add(HALT);
            arrayBlockingQueueInput.put(list);
            results.clear();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
公共静态类生成器实现可运行{
@凌驾
公开募捐{
试一试{
FileReader file=newfilereader(“src/testText.txt”);
BufferedReader br=新的BufferedReader(文件);
而((textLine=br.readLine())!=null){
if(textLine.isEmpty()){
继续;
}
/*从文本中删除标点符号,但对某些单词有用的标点符号除外。
*这些单词的示例是“不”或“重新输入”*/
textLine=textLine.replaceAll(“[[\\W]&&&&[^']&&[^-]]”,“”);
/*将所有双空格替换为单空格。
*稍后我们将在这些空白处拆分文本*/
textLine=textLine.replaceAll(“\\s\\s+”,”);
textLine=textLine.replaceAll(“\\n”和“).replaceAll(“\\r”和“);
if(results.isEmpty()){
结果。添加(文本行);
继续;
}

if(results.size())感谢您的回复!我已经尝试过了,但它仍然显示队列为空。当我打印arrayBlockingQueueInput.take()方法时,它显示了四个空括号(我想对于我启动的四个使用者)。我的程序也一直在运行。@NickSchokker如果文件的记录小于
大小,在
生产者中循环
时,您需要在
之后执行相同的操作。您是否调试了
生产者
以确保在添加到队列之前
结果
包含哪些数据?我确实在之后添加了它,而我哦,还有。我还调试了r