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