英文:
Assigning tasks to existing threads once they are free java
问题
我有一大组单词,我需要在每个单词上执行一个任务。我希望将其多线程化以增加速度。目前,我只是使用foreach循环来迭代列表中的每个项目。我想做的是有8个线程检查我给他们的单词,然后将结果写入文件。
目前,这是我正在使用的代码:
public static void main(String[] args) {
System.setProperty("http.agent", "Chrome");
readWords();
Collections.shuffle(words);
words.forEach(word -> {
if (CheckValidity.checkValidity(word)) {
System.out.println(word);
try(PrintWriter writer = new PrintWriter(new FileWriter("output.txt",true)))
{
writer.printf("%s\r\n", word);
} catch (IOException e) {
e.printStackTrace();
}
}
});
System.out.println("Done!");
}
我该如何实现多线程?我找不到任何有意义的信息,可以让我将一个值输入到一个方法中,然后由任何空闲线程处理。抱歉,如果这不完全符合多线程的工作方式,因为我以前从未编写过涉及多于一个线程的代码,所以我不知道什么是可能的,什么是不可能的。
英文:
I have a large set of words and I need to execute a task on each individual word. I want to make it multithreaded in order to increase the speed. Currently, I am just using a foreach loop to iterate through each item in the list. What I want to do is have 8 threads that check the word I give them and then write a result to a file.
Currently, this is the code I am using:
public static void main(String[] args) {
System.setProperty("http.agent", "Chrome");
readWords();
Collections.shuffle(words);
words.forEach(word -> {
if (CheckValidity.checkValidity(word)) {
System.out.println(word);
try(PrintWriter writer = new PrintWriter(new FileWriter("output.txt",true)))
{
writer.printf("%s\r\n", word);
} catch (IOException e) {
e.printStackTrace();
}
}
});
System.out.println("Done!");
}
How would I implement this in multithreading? I couldn't find any information that made sense to me where I could input a value into a method any free thread. Sorry if this isn't quite how multithreading works, i've never written anything with more than one thread before so I don't know what's possible and whats not.
答案1
得分: 1
将调用 CheckValidity
的操作并行化的最快方法是使用并行流(parallel Stream)。类似于以下示例:
public static void main(String[] args) {
List<String> words = readWords();
Collections.shuffle(words);
words.stream()
.unordered()
.parallel()
.filter(CheckValidity::checkValidity)
.forEach(word -> {
System.out.println(word);
try (PrintWriter writer = new PrintWriter(new FileWriter("output.txt", true))) {
writer.printf("%s\r\n", word);
} catch (IOException e) {
e.printStackTrace();
}
});
System.out.println("Done!");
}
然而,如果您的应用程序还在其他方面并行执行操作,那么这不应该是您的生产解决方案。因为这在内部使用了常见的 ForkJoinPool,并且用非 CPU 绑定操作阻塞它可能会减慢应用程序的其他部分(例如其他并行流)。
对于更可靠的解决方案,您应该查看 ThreadPoolExecutor,它允许创建具有定义大小、超时等的单独线程池。
英文:
The quickest way to parallelize your calls to CheckValidity
would be to use a parallel Stream. Something like
public static void main(String[] args) {
List<String> words = readWords();
Collections.shuffle(words);
words.stream()
.unordered()
.parallel()
.filter(CheckValidity::checkValidity)
.forEach(word -> {
System.out.println(word);
try(PrintWriter writer = new PrintWriter(new FileWriter("output.txt",true)))
{
writer.printf("%s\r\n", word);
} catch (IOException e) {
e.printStackTrace();
}
});
System.out.println("Done!");
}
However, this should not be your production solution if your application also does other things in parallel, as this internally uses the common ForkJoinPool, and blocking that with non-CPU bound operations may slow down other parts of your application (for example other parallel streams).
For a more robust solution, you should have a look at ThreadPoolExecutor, which allows to create separate thread pools with defined sizes, timeouts etc.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论