【问题标题】:How to correctly implement Runnable for searching an element in a Hashtable?如何正确实现 Runnable 以在 Hashtable 中搜索元素?
【发布时间】:2017-02-16 16:29:47
【问题描述】:

因此 ArrayList “comb” 包含长度相等的字符串和一些字符的变体。在最坏的情况下,这个列表可以包含大约 100,000 个单词。函数 checkWord(String str) 将一个单词作为参数并检查该单词是否存在于 Hashtable 字典中(其中包含另外 90,000~ 个单词,一个文本文件已读入此哈希表)。所以基本上代码需要检查列表“comb”中的哪些单词出现在HashTable“字典”中。在最坏的情况下,此搜索最多需要 5 分钟。我想实现 Runnable 并将其并行化,但不确定如何去做。

例如:列表梳包含 CURMUDGEON 的各种拼写错误和正确的单词本身。此列表包含其中的 98415 个。 CURMUEGEON CURMUEGEOH CURMUEGEOJ CURMUEGEKN 等等。因此,检查这些单词中的每一个是否存在于哈希表中需要 200 秒。这次我要降级了

class key implements Runnable{
    public static ArrayList<String> comb;
    public static Hashtable<String,String> dictionary; 
    public static void main(String[] args) throws IOException{
        key obj = new key();
        Thread thread1 = new Thread(obj);
        thread1.start();
    }
    public static Boolean checkWord(String str){
                String toCheck = str.toLowerCase();
                if(dictionary.contains(toCheck)){
                    return true;
                }
                else
                 return false;
      }
        public void run(){
            for(String x:comb)
                if ( checkWord(x) )
                    filtered.add(x);

        }

【问题讨论】:

  • 在 HashMap 中查找 100,000 个单词应该是几秒钟的时间,如果那样的话。进行多线程是没有意义的。你确定dictionary 真的是一个基于哈希表的数据结构吗?请提供minimal reproducible example
  • @JonSkeet 谢谢,我已经编辑并更新了我的问题。
  • 嗯 ... 1) 为什么这是Map 而不是SetMap 的值是什么? 2) 并行化是以复杂性为代价的。如果这些值无关紧要,我们确实为set intersection 提供了更好的算法。
  • @dhke 谢谢!从 hashmap 更改为 hashset 解决了这个问题!
  • @daipayan 这真的很奇怪。您使用的是什么运行时环境?因为在 OpenJDK 和朋友中,HashSetimplemented on top of HashMap

标签: java multithreading algorithm hashtable runnable


【解决方案1】:

HashTable 是一个遗留的 JDK1.0 API 类,具有非常强的并发保证。在particular

与新的集合实现不同,Hashtable 是同步的。

这意味着对Hashtable的每一次操作都需要获取监视器锁,这是重复查找的性能杀手。最好遵循 JDK javadocs 中给出的建议:

如果不需要线程安全的实现,建议使用 HashMap 代替 Hashtable。如果需要线程安全的高并发实现,建议使用 ConcurrentHashMap 代替 Hashtable。

【讨论】:

    【解决方案2】:

    为了提高效率,您需要多个独立测试不同范围的梳状列表的 Runnable,例如

    public class MySearcher implements Runnable {
      ArrayList list;
      int startIdx, endIdx;
      public MySearcher(list, startIdx, endIdx) {
        // copy into object fields
      }
      public void run () {
        // test all values in the list between startIdx and endIdx
        // put results into a data structure. Create a method to get/return that data structure
      }
    }
    

    然后你可以为你所有的 Runnables 使用一个 ExecutorService(关于用法,请参阅 javadoc:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-14
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 2014-12-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多