Java并发:计算字符串

时间:2018-10-20 12:33:35

标签: java multithreading counting

在进行一些Java练习时,我遇到了一个任务,其中包括多线程和并发。到目前为止,我完全没有经验。基础是一个Java类/程序,它具有对字符串中的字符进行计数的功能。该函数提供了一个字符串和一个ConcurrentHashMap,并使用小写字母(每个char作为键)以及每个char的出现作为值(作为整数)。该程序有效(使用Hashmap且不使用多线程,这意味着无需实现可运行且无需公共void运行)。

我了解ConcurrentHashMap的用法以启用多线程,并因此实现了ConcurrentHashMap(使用它代替HashMap)。此外,我知道,我的类需要实现可运行的,因此具有公共void run()方法。

我的目标:

我想知道如何启动三个线程,这三个线程都计算字符在同一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() {

    }
}

1 个答案:

答案 0 :(得分:3)

我在您的问题中看到的一个问题:

  

我是对的,有人利用这种实现使程序运行得更快吗?

不,在这种情况下不行。您必须了解创建和启动线程,然后以某种方式同步以避免竞争条件(以实现正确的确定性行为)不是免费的。

线程是基础操作系统的资源。创建,启动,管理它们需要花费时间

因此:使用多个线程不会自动转换为“我的程序运行速度更快”。当并行处理数据的好处大于创建这些线程的初始成本时,多个线程只会使事情“更快”。当然,您还需要能够并行运行线程的硬件。 如果您的硬件一次只能运行一个线程,那么做的事情仅使用CPU(并且永远不等待某些外部输入),那么拥有多个线程将总是 慢一点。

现在,您的任务是计算人类用户提供的短字符串中的字符。这可以通过单线程迭代字符串并完成其工作来最快地解决。因此:与直接使用单线程解决方案相比,您的多线程程序最有可能会慢很多。

另一方面,如果您的任务是读取数千个文件和数百万行文本,例如为全文搜索建立某种索引,那么当然:使用多个线程可以极大地提高速度延长整体执行时间。

除此之外:到目前为止,您编写的代码没有任何作用。要制定合理的程序,您需要:

  • run()方法中有一些代码。
  • 然后创建多个并行调用该run()方法的线程

当然,要求您对数据进行合理的分区。例如,您可以让每个线程计数您输入的特定 sub字符串