多线程程序花费的时间比单线程(Java)长

我必须编写一个程序来读取文件中的所有单词,并确定每个单词使用了多少次。我的任务是使用多线程来加快运行时间,但是单线程程序的运行速度比多线程程序快。我曾尝试研究此问题的解决方案,但很多解释只会让我更加困惑。我对使用线程很陌生,想知道是否有人可以指出正确的方向修复我的代码,以便创建线程的开销不会导致程序运行速度比单个线程慢。

public class Main 
{
final static int THREADS = 4;
static HashMap<String, Integer> map = new HashMap<>();
static List<String> file = new ArrayList<String>();
static String filename = "D:\\yes.txt";
static int count;




public static void main(String args[]) throws Exception
{
    long startTime = System.nanoTime();
    Monitor m = new Monitor();
    final Queue<String> dataQueue = new ConcurrentLinkedQueue<>();

    try ( Scanner in = new Scanner(new File(filename))) 
    {
                while ( in.hasNext() ) 
                {
                    dataQueue.add( in.next() );
                }
    }
    catch ( IOException e ) 
    {
        e.printStackTrace();
    }


    Thread T1 = new Thread( new WordCount(m, map, dataQueue ));
    Thread T2 = new Thread( new WordCount(m, map, dataQueue ));
    Thread T3 = new Thread( new WordCount(m, map, dataQueue ));
    Thread T4 = new Thread( new WordCount(m, map, dataQueue ));

    T1.start();
    T2.start();
    T3.start();
    T4.start();


     //wait for threads to end
       try {
       T1.join();
       T2.join();
       T3.join();
       T4.join();
    } catch ( Exception e) {
       System.out.println("Interrupted");
    }   

    Set<String> keys = map.keySet();
    for (String key : keys) 
    {
        System.out.println(key);
        System.out.println(map.get(key));
    }
    long endTime = System.nanoTime();
    System.out.println("Thread Took "+((endTime - startTime)/100000) + " ms");


}
}
public class WordCount implements Runnable
{

    private Monitor m;
    private Queue<String> dataQueue;
    private HashMap<String, Integer> map;

    public WordCount(Monitor m, HashMap<String, Integer> map,Queue<String> dataQueue)
    {
        this.m = m;
        this.dataQueue = dataQueue;
        this.map = map;
    }

    @Override public void run()
    {
        while ( !dataQueue.isEmpty() ) 
        {
            String line = dataQueue.poll();
            m.keySet(map, line);
        }
    }   
}
public class Monitor 
{
    public synchronized void keySet(HashMap<String, Integer> map, String word) 
    {
        String[] words = filterIllegalTokens(word );
        String[] lowerCaseWords = mapToLowerCase( words );
         for ( String s : lowerCaseWords ) {


        if (map.containsKey(s)) 
        {
            map.put(s, map.get(s) + 1);

        } 
        else 
        {
            map.put(s, 1);
        }
         }
    }
    public  String[] filterIllegalTokens(String words)
    {
        List<String> filteredList = new ArrayList<>();

        if ( words.matches( "[a-zA-Z]+" ) ) {
                filteredList.add( words );
            }

        return filteredList.toArray( new String[filteredList.size()] );
    }
    public  String[] mapToLowerCase( String[] words )
    {
        String[] filteredList = new String[words.length];
        for ( int i = 0; i < words.length; i++ ) {
            filteredList[i] = words[i].toLowerCase();
        }
        return filteredList;
    }
}

这是我的三个班级。有任何提示或建议吗?

斯特凡

一条经验法则说,您需要一个CPU内核用于操作系统,其他的可以用于程序。因此,您至少需要5个CPU内核才能获得最佳性能。

创建这几个线程的开销并不重要。当您以毫秒为单位启动多个线程时,这将变得更加相关。

代码中的主要问题是您访问共享内存区域中的数据的总时间为90%。在这种情况下,我们正在讨论ConcurrentLinkedQueueMonitor.keySet()方法。当一个线程访问这些对象时,其他3个线程必须等待。当长时间运行程序时,您可能会注意到只使用了总CPU能力的一小部分。

为了提高性能,我建议在启动线程之前将作业队列分成4个数据包,这样每个线程便可以处理自己的数据包,而无需等待其他线程。每个线程也应将其结果收集在一个单独的容器中。然后最后(在线程完成之后),您可以合并四个结果。

如果您的工作线程更加复杂,那么您的问题就不会那么困难了。例如,如果对容器的访问仅花费总时间的10%(而某些计算花费90%),则线程同步的开销也将相对于总执行时间少得多。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

多线程程序花费的时间比单个线程(JAVA)

来自分类Dev

java-多线程中的简单计算所需时间比单线程中的更长

来自分类Dev

多线程程序比单线程慢

来自分类Dev

单线程CPU上的多线程应用程序?

来自分类Dev

java-简单计算在多线程中比在单线程中需要更长的时间

来自分类Dev

Java是默认的单线程还是多线程?

来自分类Dev

Java是默认的单线程还是多线程?

来自分类Dev

同步多线程与单线程

来自分类Dev

与单线程相比,多线程更快

来自分类Dev

多线程比单线程快吗?

来自分类Dev

多线程程序的运行速度比单线程程序慢

来自分类Dev

为什么多线程版本需要与单线程版本相同的时间?

来自分类Dev

如何在Visual Studio中将多线程应用程序调试为单线程

来自分类Dev

单线程与多线程JMS生产者

来自分类Dev

多线程图像处理比单线程慢?

来自分类Dev

为什么我的多线程比单线程慢?

来自分类Dev

多线程图像处理比单线程慢?

来自分类Dev

C ++多线程代码与单线程同时执行

来自分类Dev

ruby 中的多线程比单线程慢

来自分类Dev

Java单线程CPU使用和多线程CPU使用

来自分类Dev

Java中单线程死锁

来自分类Dev

Java中的单线程查询

来自分类Dev

Java简单和单线程IllegalMonitorStateException

来自分类Dev

使用多线程程序而不是使用单线程程序并行编译项目是否具有性能优势?

来自分类Dev

将单线程应用程序迁移到多线程,并行执行,蒙特卡洛仿真

来自分类Dev

单线程Java应用程序可启动70多个线程

来自分类Dev

避免单线程死锁

来自分类Dev

Javascript是如何单线程的?

来自分类Dev

避免单线程死锁

Related 相关文章

热门标签

归档