java - 消费者类未写入列表多线程应用程序Java

标签 java multithreading threadpool consumer

我对这个消费者类别有疑问。 当我运行程序时,池中的每个线程都会出现越界异常。 我有 sysout 列表大小,但由于某种原因它为零。 请参阅下面我的代码。 我对已设置的列表不感兴趣,但我无法弄清楚。 该程序的所有其他部分都在工作并经过测试,只是最后一部分给我带来了问题。 任何提供的帮助将不胜感激。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Consumer implements Runnable {
    private BlockingQueue<Shingle> q;
    private int k;
    private int[] minHashes;
    private Map<Integer, List<Integer>> map = new HashMap<>();
    private ExecutorService pool;

    public Consumer(BlockingQueue<Shingle> q, int k, int poolSize) {
        super();
        this.q = q;
        this.k = k;
        pool = Executors.newFixedThreadPool(poolSize);
        init();
    }

    public void init() {
        Random random = new Random();
        minHashes = new int[k];
        for (int i = 0; i < minHashes.length; i++) {
            minHashes[i] = random.nextInt();
        }
    }

    public void run(){
        try {
            int docCount = 2;
            while (docCount > 0) {
                Shingle s = q.take();
                if (s instanceof Poision) {
                    docCount--;
                } else {
                    pool.execute( new Runnable() {
                        public void run() {
                            for (int i = 0; i < minHashes.length; i++) {
                                int value = s.getHashCode() ^ minHashes[i]; // ^ - xor(Random generated key)
                                List<Integer> list = map.get(s.getDocId());
                                if (list == null) {
                                    list = new ArrayList<Integer>(k);
                                    for (int j = 0; j < list.size(); j++) {
                                        list.set(j , Integer.MAX_VALUE);
                                    }
                                    map.put(s.getDocId(), list);
                                } else {
                                    if (list.get(i) > value) {
                                        list.set(i, value);
                                    }
                                }
                            }
                        }
                    });

                }
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

最佳答案

问题是这一行

list = new ArrayList<Integer>(k);

创建初始容量等于k的列表,而不是大小等于k。所以你的列表有 0 个元素和 for 循环

for (int j = 0; j < list.size(); j++) {
   list.set(j , Integer.MAX_VALUE);
}

不执行任何迭代。然后,您将空列表添加到 map 中,并且由于 list.get(i) 抛出异常。

请将您的 for 循环更改为

for (int j = 0; j < minHashes.length; j++) {
    list.add(Integer.MAX_VALUE);
}

实际将元素添加到列表中。

关于java - 消费者类未写入列表多线程应用程序Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48153928/

相关文章:

java - 从 URL 下载 Java 文件 1) 您不知道扩展名[例如 .jpg] 或 2) 正在重定向到文件

c# - 线程控制调用

c++ - 使用 PBO 上传 OpenGL 纹理?

java - 使用 JMS 或 ThreadPool 发送电子邮件

java - 将多线程与 RMI 结合使用

java - 在 Windows 中使用 Java 网络摄像头界面进行人脸检测

java - POJ 2136 垂直直方图

java - 使用 hibernate-search-4.1.1.Final.jar 进行 Hibernate 全文搜索,但无法解决查询生成器等错误

java - 处理在单独线程中抛出的异常的最佳方法是什么?

c# - 如何限制创建的任务数量?