Java并发数:统计String的字符数
Java Concurrency: Count characters of String
在做一些 Java 练习时,我遇到了一个任务,包括多线程和并发。到目前为止,我完全没有这方面的经验。基础是一个javaclass/program,它有一个统计字符串中字符数的函数。该函数由字符串和一个 ConcurrentHashMap 提供,其中字母表为小写(每个字符作为键),每个字符的出现作为值(作为整数)。该程序有效(使用 Hashmap 并且没有多线程,这意味着没有实现 运行nable 并且没有 public void 运行)。
我了解 ConcurrentHashMap 的用法以启用多线程并因此实现了 ConcurrentHashMap(使用它而不是 HashMap)。此外我知道,我的 class 需要实现 运行nable,因此有一个 public void 运行 () 方法。
我的目标:
我想知道,如何启动三个线程,它们都计算同一个String的字符出现次数并写入ConcurrentHashMap。
我说得对吗,有人利用这种实现方式让程序运行更快? (已回答)
更多信息
从答案中可以看出,不清楚为什么要这样做。这是一项练习任务。稍后,我可能会添加大文本文件的文件输入(也可能不会,这是实践,我不知道)。
最终编辑
因此,多线程对此没有用。无需进一步回答。
到目前为止我的代码:
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
class WordCounter implements Runnable {
// method to count characters in given string
static void characterCount(String inputString, ConcurrentHashMap<Character, Integer> charCountMap) {
// Converting String to lowercase
inputString = inputString.toLowerCase();
// Converting given string to char array
char[] strArray = inputString.toCharArray();
// checking each char of strArray
for (char c : strArray) {
if (charCountMap.containsKey(c)) {
// If char is present in charCountMap,
// incrementing it's count by 1
charCountMap.put(c, charCountMap.get(c) + 1);
}
}
// Printing the charCountMap
for (Map.Entry entry : charCountMap.entrySet()) {
if(!entry.getValue().equals(0)){
System.out.println(entry.getKey() + " " + entry.getValue());
}}
}
// Main
public static void main(String[] args)
{
// Creating a HashMap containing alphabet in lower case
// as a key and occurrences as a value (initialized with value: 0)
ConcurrentHashMap<Character, Integer> charCountMap
= new ConcurrentHashMap<>();
for (char ch = 'a'; ch <= 'z'; ++ch)
charCountMap.put(ch, 0);
String str = "GGACACGTagGcGT";
characterCount(str, charCountMap);
}
@Override
public void run() {
}
}
我在你的问题中看到的一个问题:
Am I right, that one utilizes this kind of implementation to make the program run faster?
不,在这种情况下不是。您必须了解创建和启动线程,然后 同步 它们以某种方式避免竞争条件(以实现正确的、确定性的行为)并不是免费的。
线程是底层操作系统的资源。创建、启动、管理它们需要 时间。
因此:使用多线程不会自动转化为 "my program runs faster"。当并行处理数据的优势超过创建这些线程的初始成本时,多个线程只会使事情 "faster" 。当然,您还需要能够并行处理 运行 个线程的硬件。 如果你的硬件一次只能运行一个线程,然后做一些只使用CPU的事情(并且从不等待一些外部输入)然后拥有多个线程会 always 变慢。
现在,您的任务是计算人类用户提供的短字符串中的字符数。这可以通过一个线程迭代字符串并完成它的工作来最快地解决。因此:与直接的单线程解决方案相比,您的多线程程序很可能会慢很多。
另一方面,如果您的任务是读取包含数百万行文本的数千个文件,例如为全文搜索构建某种索引,那么当然:使用多线程可以显着加快整体执行时间。
除此之外:到目前为止您编写的代码没有任何作用。要制作合理的程序,您需要:
- 在
run()
方法中有一些代码。
- 然后创建多个并行调用
run()
方法的线程
当然,也需要你对数据进行合理的分区。例如,您可以让每个线程计算输入的特定 子字符串。
在做一些 Java 练习时,我遇到了一个任务,包括多线程和并发。到目前为止,我完全没有这方面的经验。基础是一个javaclass/program,它有一个统计字符串中字符数的函数。该函数由字符串和一个 ConcurrentHashMap 提供,其中字母表为小写(每个字符作为键),每个字符的出现作为值(作为整数)。该程序有效(使用 Hashmap 并且没有多线程,这意味着没有实现 运行nable 并且没有 public void 运行)。
我了解 ConcurrentHashMap 的用法以启用多线程并因此实现了 ConcurrentHashMap(使用它而不是 HashMap)。此外我知道,我的 class 需要实现 运行nable,因此有一个 public void 运行 () 方法。
我的目标:
我想知道,如何启动三个线程,它们都计算同一个String的字符出现次数并写入ConcurrentHashMap。
我说得对吗,有人利用这种实现方式让程序运行更快? (已回答)
更多信息
从答案中可以看出,不清楚为什么要这样做。这是一项练习任务。稍后,我可能会添加大文本文件的文件输入(也可能不会,这是实践,我不知道)。
最终编辑
因此,多线程对此没有用。无需进一步回答。
到目前为止我的代码:
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
class WordCounter implements Runnable {
// method to count characters in given string
static void characterCount(String inputString, ConcurrentHashMap<Character, Integer> charCountMap) {
// Converting String to lowercase
inputString = inputString.toLowerCase();
// Converting given string to char array
char[] strArray = inputString.toCharArray();
// checking each char of strArray
for (char c : strArray) {
if (charCountMap.containsKey(c)) {
// If char is present in charCountMap,
// incrementing it's count by 1
charCountMap.put(c, charCountMap.get(c) + 1);
}
}
// Printing the charCountMap
for (Map.Entry entry : charCountMap.entrySet()) {
if(!entry.getValue().equals(0)){
System.out.println(entry.getKey() + " " + entry.getValue());
}}
}
// Main
public static void main(String[] args)
{
// Creating a HashMap containing alphabet in lower case
// as a key and occurrences as a value (initialized with value: 0)
ConcurrentHashMap<Character, Integer> charCountMap
= new ConcurrentHashMap<>();
for (char ch = 'a'; ch <= 'z'; ++ch)
charCountMap.put(ch, 0);
String str = "GGACACGTagGcGT";
characterCount(str, charCountMap);
}
@Override
public void run() {
}
}
我在你的问题中看到的一个问题:
Am I right, that one utilizes this kind of implementation to make the program run faster?
不,在这种情况下不是。您必须了解创建和启动线程,然后 同步 它们以某种方式避免竞争条件(以实现正确的、确定性的行为)并不是免费的。
线程是底层操作系统的资源。创建、启动、管理它们需要 时间。
因此:使用多线程不会自动转化为 "my program runs faster"。当并行处理数据的优势超过创建这些线程的初始成本时,多个线程只会使事情 "faster" 。当然,您还需要能够并行处理 运行 个线程的硬件。 如果你的硬件一次只能运行一个线程,然后做一些只使用CPU的事情(并且从不等待一些外部输入)然后拥有多个线程会 always 变慢。
现在,您的任务是计算人类用户提供的短字符串中的字符数。这可以通过一个线程迭代字符串并完成它的工作来最快地解决。因此:与直接的单线程解决方案相比,您的多线程程序很可能会慢很多。
另一方面,如果您的任务是读取包含数百万行文本的数千个文件,例如为全文搜索构建某种索引,那么当然:使用多线程可以显着加快整体执行时间。
除此之外:到目前为止您编写的代码没有任何作用。要制作合理的程序,您需要:
- 在
run()
方法中有一些代码。 - 然后创建多个并行调用
run()
方法的线程
当然,也需要你对数据进行合理的分区。例如,您可以让每个线程计算输入的特定 子字符串。