使用Java中的线程对列表进行排序

时间:2016-06-30 17:19:51

标签: java multithreading sorting java-threads

我有一个单词列表,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秒,下一部分任务是使用Threads并在更短的时间内进行排序。我打算使用5个Threads,我可以使用它们并单独运行,说Thread1可以排序1-200,Thread2可以排序201-400,Thread3可以排序401-600 ......但最后我会有5个不同的列表?在Thread1列表上会有10只狗,在Thread2列表中会有20只狗......在控制台上混合......我希望它像上面的例子一样使用5个线程,是否可能?你能不能给我一些提示,我是Threads的新手。

编辑:我使用内置的排序功能,暂时使用哪种排序算法并不重要。任务不是使用最好的排序算法,而是使用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;
        }   
    }
}

1 个答案:

答案 0 :(得分: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