我对这个消费者类别有疑问。 当我运行程序时,池中的每个线程都会出现越界异常。 我有 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/