【问题标题】:Sorting a list with Threads in Java在 Java 中使用线程对列表进行排序
【发布时间】:2016-06-30 17:19:51
【问题描述】:

我有一个单词列表,1000 个单词,我应该将它们从出现次数最多到出现最少的顺序列出。

喜欢:

 Dog, 100 times
 Cat, 50 times
 Fish, 40 times
 Monkey, 10 times
 Bird, 10 times
 Camel, 10 times
 .
 .
 .
 Lion, 1 times
 Tiger, 1 times

我这样做并使用了一个 while 循环,但它需要大约 10 秒,任务的下一部分是使用线程并在更短的时间内进行排序。我计划使用 5 个线程,我可以使用它们并单独运行,比如 Thread1 可以排序 1-200,Thread2 可以排序 201-400,Thread3 可以排序 401-600 ......但最后我会有 5 个不同的列表? Thread1 列表中有 10 条狗,Thread2 列表中有 20 条狗...在控制台上混合...我希望它像上面的示例一样使用 5 个线程,这可能吗?您能否提供一些提示,我是 Threads 新手。

编辑:我正在使用内置的排序功能,目前我使用哪种排序算法并不重要。任务不是用最好的排序算法,而是用线程排序。

代码:

//This is the list
    ArrayList<String> animalList = new ArrayList<String>();

//This is the map from the list
    Map<String, Integer> map = new HashMap<String, Integer>();
    for (String temp : animalList) {
        Integer count = map.get(temp);
        map.put(temp, (count == null) ? 1 : count + 1);
    }

//This is the final map
    TreeMap<String, Integer> sortedMap = sortMapByValue(map); 


public static TreeMap<String, Integer> sortMapByValue(Map<String, Integer> map){
    Comparator<String> comparator = new ValueComparator(map);
    TreeMap<String, Integer> result = new TreeMap<String, Integer>(comparator);
    result.putAll(map);
    return result;
}


public class ValueComparator implements Comparator<String>{

    HashMap<String, Integer> map = new HashMap<String, Integer>();

    public ValueComparator(Map<String, Integer> map2){
        this.map.putAll(map2);
    }

    @Override
    public int compare(String s1, String s2) {
        if(map.get(s1) >= map.get(s2)){
            return -1;
        }else{
            return 1;
        }   
    }
}

【问题讨论】:

  • 什么排序算法?可能是第一个寻求优化的地方,而不是尝试通过多线程来加速。
  • 这不可能花费将近 100 秒。你在某处做着非常低效的事情
  • @Cruncher 我不想对猫和狗进行分类...... 100 只是一个例子。
  • 首先,应该使用quicksortmerge sort等分而治之的算法。它们更容易通过多线程实现。
  • 如果你需要 100 秒来对 1000 个字符串进行排序,那么你的解决方案很糟糕。如果您使用的是 java,只需使用内置的排序功能;这几乎可以保证您永远不会开发出更好的东西。如果您将此作为学习经验,请自己编写排序并将其(排序时间)与内置的 java 排序进行比较,作为“质量”的衡量标准。另外,正如 dorukayhan 所提到的,请阅读合并排序。

标签: java multithreading sorting java-threads


【解决方案1】:

Java 中的大多数线程不会同时执行(除非每个内核都有一个线程),并且会发生线程之间不断变化的流程,因此如果结果取决于操作顺序,它会很快变得非常不可预测。

有一些方法可以避免这种情况。其中之一是synchronization。也就是说(简单地说)在另一个线程完成它之前,您不会让其他线程访问您的代码的某些部分。此解决方案可以使您的程序以deadlock 结尾。这对您并没有太大帮助,因为如果您在另一个人说对您的列表进行排序时停止您的线程,那么您从使用线程中得不到任何好处。

您可以做的是尝试以不依赖于执行顺序的方式使用线程。 例如,您可以让一个线程处理前 200 个单词,另一个处理接下来的 200 个单词,依此类推。那么你应该只将结果组合成递归的merge-sort,就像时尚一样。


线程是提高程序执行时间的好方法。但是...如果您需要大约 100 秒来对一千个单词的列表进行排序,那么您的算法可以得到改进。

你可以做的是首先使用(例如字母)排序算法改进你的代码,然后让你的列表按名称排序(你可以在 O(n·ln(n) 中做到这一点),例如merge-sortquick-sortheap-sort)。一旦你对你的列表进行了排序,你只需要 O(n) 一次来提取你的频率,方法是在列表上方一次和另一个 O(m·ln(m)),其中 m 是频率列表的长度,来排序该列表按频率降序排列。

总而言之,你的结果可能是 O(n·ln(n)+n+m·ln(m)),在最坏的情况下是 O(2·n·ln(n) + n ) (如果没有两个词是相等的)。这仍然是 O(n·ln(n))。

所有计算机都可以在不到 100 秒的时间内计算出 O(n·ln(n)) 级的东西:P

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-09
    • 1970-01-01
    相关资源
    最近更新 更多