4

나는 보고서의 실행을 변경하고 동시에 수행하도록하고있다. 'serail mode'에서 실행 테스트는 30 초가 걸리며 동시 모드를 사용할 때는 27 초가 걸릴 것입니다. 직렬로 수행해야하는 몇 가지 단계를 수행해야하며 결과가 좋을 것입니다.왜 newFixedThreadPool의 증가로 인해 성능이 저하됩니까?

난 아직도하지 않는 것은이 라인 :

내 컴퓨터가 2x2.6 GHz의 쿼드 코어로 무장하고 인 newFixedThreadPool가 높은 경우 나 실행 시간이 감소 할 것으로 기대
ExecutorService executor = Executors.newFixedThreadPool(4); 

(16). 사실, newFixedThreadPool을 늘리면 실행 속도가 느려집니다. 이것은 질문을 구걸한다 : 나는 무엇을 잘못하고 있는가, 또는 무엇을 이해하지 못하는가?!?!

내 실행 결과 스크린 샷 2 장을 포함하고 있습니다.

A.의 newSingleThreadExecuter - 23 초

B. 인 newFixedThreadPool에서 실행 (4) - 43 초에서 실행.

'Worker'를 제출할 때마다 system.out에 currentTimeMillis가 표시되고 "fatched tkt"결과는 db에서 데이터를 가져 오는 데 걸리는 밀리 초입니다. (전략 A에서는 ~ 3ms, B에서 최대 7ms). 당신이 작업에 스레드를 추가하는 경우

Stopper stopper = new Stopper(); 
    for (Long iNum : multimap.asMap().keySet()) 
    { 
     List<Long> tickets = (List<Long>) multimap.get(iNum); 
     for (Long ticketNumber : tickets) 
     { 
       pojoPks = getPkData(iNum); 
       Callable<PojoTicket> worker = new MaxCommThread(ticketNumber, pojoPks); 
       Future<PojoTicket> submit = executor.submit(worker); 
       futures.add(submit); 
     } 
    } 

    System.out.println("futurues: " +futures.size()); 
    for (Future<PojoTicket> future : futures) 
    { 
     try 
     { 
      PojoTicket pojoTicket = future.get(); 
      //do the rest here 

     } catch (InterruptedException e) 
     { 
      System.out.println("---------------------->InterruptedException"); 
     } catch (ExecutionException e) 
     { 
      System.out.println("---------------------->ExecutionException"); 
     } 
    } 

    executor.shutdown(); 
    stopper.stop(); 

enter image description here

enter image description here

+1

어. 왜 많은 ExecutionException이 발생합니까? – Gray

+0

Worker 클래스 코드를 게시 할 수 있습니까? 그것은 일어나는 일에 대해 더 많은 단서를 줄 수 있습니다. –

답변

5

더 나는 일반적으로 느린 실행

을 인 newFixedThreadPool을 증가시키고 그렇지 않습니다 두 가지 이유로 다음 중 하나 일 수 있습니다.

  • 각 작업은 일종의 자원에서 동기화되어야하므로 잠금 경합으로 인해 독립적으로 실행되지 않습니다.

  • 작업을 수행 할 CPU 작업이 많지 않습니다. IO 바운드 프로세스에 스레드를 추가해도 IO 채널이 이미 최대 값을 초과 할 수 있으므로 작업 속도가 향상되지 않습니다.

그러나 애플리케이션이 절반으로 빠르게 실행되는 것은 흥미로운 상황입니다. 나는 그것들이 둘의 조합이라고 짐작할 수 있습니다.

한 가지 시도는 1 개의 스레드로 시작한 다음 2를 시도하는 것입니다. 더 빨리 실행되지 않으면 먼저 작업간에 공유되는 잠금을 살펴보십시오. 각 작업에 의해 수정되는 동시 콜렉션 또는 다른 오브젝트는 무엇입니까? 잠금 수를 줄이거 나 스레드에 임시 정보를 저장 한 다음 한 번 잠 가서 중앙 개체를 업데이트하십시오.

또한 시스템 통계를보고 IO 채널이 초과되었는지 확인할 수 있습니다. 여기에 일반적인 문제를 디스크하십시오. 메모리 디스크에서 실행할 수 있는지 확인하여 응용 프로그램이 더 빨리 실행되는지 확인하십시오. 그게 당신이 입출력 경계라는 지표가 될 것입니다.

마지막으로 작업을 수확 할 때 ExecutionException이 표시되는 이유를 살펴 보겠습니다.이것은 다른 문제의 지표 일지 모르지만 먼저 이것을 이해해야합니다.

+1

당신의 답을 바탕으로, 나는 코드를 파헤 치고 문제를 발견했습니다 : 나는 문제를 만든 동기화 된 방법을 가지고 있습니다. 이제이 방법을 개선하고 멀티 스레딩을 위해이를 수정하는 방법을 알아야합니다. 감사! – adhg

+0

우수 @ adhg. 다행히 도울 수있어. – Gray

+0

@Gray "디스크는 일반적인 문제입니다. 응용 프로그램이 더 빨리 실행되는지 확인하기 위해 메모리 디스크에서 실행할 수 있는지 확인하십시오 .IO 경계에 있음을 나타내는 지표가됩니다." 여기서 Disk가 무엇을 의미하는지 설명 할 수 있습니까? – Geek

관련 문제