Java parallel()的并发问题
我有一个问题,这段代码在每次运行时返回的值都不相同。我认为这是因为它不是线程安全的,并且我在使用parallel()时遇到了一些并发性问题。我曾尝试使用拆分器,这是可行的,但运行时性能差3倍,与sequental相同。我还能怎么做 附言: traverseDirectory返回目录中所有.txt文件的BlockingQueueJava parallel()的并发问题,java,concurrency,thread-safety,java-stream,spliterator,Java,Concurrency,Thread Safety,Java Stream,Spliterator,我有一个问题,这段代码在每次运行时返回的值都不相同。我认为这是因为它不是线程安全的,并且我在使用parallel()时遇到了一些并发性问题。我曾尝试使用拆分器,这是可行的,但运行时性能差3倍,与sequental相同。我还能怎么做 附言: traverseDirectory返回目录中所有.txt文件的BlockingQueue try { pq = traverseDirectory(dir, pq); while(!pq.isEmpty()){ File f
try {
pq = traverseDirectory(dir, pq);
while(!pq.isEmpty()){
File f = pq.take();
LineNumberReader lr = new LineNumberReader(new FileReader(f));
lr.lines()
.parallel()
.forEach((line) -> {
String[] words = line.split("\\s+");
for( String word : words ){
wordList.add(word);
}
}); // foreach
} // while
} //try
catch (IOException | InterruptedException e) {}
System.out.println("size: " + wordList.size());
编辑
我忘了提到,我需要记录在哪一行找到了这个词 列表不能保证线程安全,因此当您写入单词列表时,并发写入列表可能会相互干扰,特别是当列表在结构上被修改以容纳附加值时。文档建议确保在这种情况下同步访问列表 最好用更多的流处理来替换
forEach
,以避免此类并发问题。不要使用forEach,请尝试以下操作
.flatMap(line -> Arrays.stream(line.split("\\s+")))
这将产生所有行中所有单词的流。然后,您可以使用.count()
终止流以获取字数,或者使用collect()
将它们添加到某种集合中
@霍尔格指出,通过反复使用字符串
regex进行拆分,每次迭代都会重新编译相同的regex。改用
.flatMap(Pattern.compile("\\s+")::splitAsStream)
每个文件只编译一次正则表达式。列表不能保证线程安全,因此当您写入word列表时,对列表的并发写入可能会相互干扰,特别是当列表在结构上被修改以容纳附加值时。文档建议确保在这种情况下同步访问列表 最好用更多的流处理来替换
forEach
,以避免此类并发问题。不要使用forEach,请尝试以下操作
.flatMap(line -> Arrays.stream(line.split("\\s+")))
这将产生所有行中所有单词的流。然后,您可以使用.count()
终止流以获取字数,或者使用collect()
将它们添加到某种集合中
@霍尔格指出,通过反复使用字符串
regex进行拆分,每次迭代都会重新编译相同的regex。改用
.flatMap(Pattern.compile("\\s+")::splitAsStream)
<> >每个文件只编译一次。正确,但是您可以考虑使用<代码> .FLAMP(模式:编译(“s++”)::SPLITASFROW)< /COD>。它确保正则表达式模式只解析一次而不是每行,并且不会为每行填充中间数组。@Holger
splitAsStream
对我来说是一个新的。你让我开心了。@Holger flatMap到底做了什么?splitAsStream
返回一个流
,因此在map()
中使用它将把你的流
变成流。使用flatMap()!顺便说一句,我需要记录在哪一行找到这个词。这是非常重要的。正确,但是你可以考虑使用<代码> .Falm(模式:编译(“s++”)::SPLITASFISH)< /COD>。它确保正则表达式模式只解析一次而不是每行,并且不会为每行填充中间数组。@HolgersplitAsStream
对我来说是一个新的。你让我开心了。@Holger flatMap到底做了什么?splitAsStream
返回一个流
,因此在map()
中使用它将把你的流
变成流。使用flatMap()!顺便说一句,我需要记录在哪一行找到这个词。这是非常重要的。