단일 스레드보다 오래 걸리는 프로그램을 멀티 스레딩 (자바)

오리 :

나는 파일에서 모든 단어를 읽고 각 단어를 사용하는 횟수를 결정하는 프로그램을 작성해야합니다. 나는 단일 스레드 프로그램이 실행 빠르게 멀티보다 실행 시간을 단축하기 위해 멀티 스레딩을 사용하는 임무 만하고 있습니다. 나는이 문제를 해결하기위한 방안을 연구 시도했다하지만 설명이 많은 단지 나를 더 혼란하고 있습니다. 내가 스레드를 사용하여 아주 새로운 해요, 그리고 스레드를 생성하는 오버 헤드가 프로그램이 단일 스레드보다 느리게 실행되지 않습니다 원인 때문에 사람이 내 코드를 고정 올바른 방향으로 날 지점 수 있는지 궁금 해서요.

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 코어가 필요합니다.

정말 중요하지 않습니다이 몇 스레드를 생성하기위한 오버 헤드. 당신이 밀리 초 withing에 스레드 수십를 시작할 때 그 관련성이 될 것입니다.

코드의 주요 문제는 전체 시간의 90 %를 공유 메모리 영역의 데이터에 액세스 할 것입니다. 이 경우 우리는 얘기 ConcurrentLinkedQueue와 동기화 Monitor.keySet()하는 방법. 하나의 스레드 액세스 이러한 개체 반면, 다른 3 개 스레드를 기다려야합니다. 당신이 오랜 시간 동안 프로그램을 실행하면 당신은 당신의 총 CPU 전력의 일부만을 사용하는 알 수 있습니다.

성능을 향상시키기 위해 당신이 스레드를 시작하기 전에 각 스레드가 다음 다른 스레드를 기다리지 않고 자신의 패킷을 처리 할 수 ​​있도록 4 개 패킷으로 작업 대기열을 분할 추천 할 것입니다. 각 스레드는 개별 용기에 그 결과를 수집한다. 그런 다음 (스레드 완료 후) 마지막으로, 당신은 네 가지 결과를 결합 할 수 있습니다.

당신의 작업자 스레드가 더 복잡 될 경우 문제가 덜 어려울 것이다. 상대적 총 실행 시간 - (어떤 계산이 90 %를 취하면서), 예를 들어, 컨테이너에 대한 접근은 전체 시간의 10 %를 취할 것인지 다음 스레드 동기화의 오버 헤드도 훨씬 덜 할 것이다.

추천

출처http://43.154.161.224:23101/article/api/json?id=13447&siteId=1