2016-08-09 3 views
0

나는 비동기식 요청을 실행할 수 있고 유행을 잊어 버릴 수있는 메소드를 가지고있다.비동기 처리를위한 Short Execived ExecutorService

방법은 다음과 같이 구현됩니다

private void publishWorkItem(final Object payload, final ZkWorkCompleteCallback callback) 
{ 
    if (payload == null) 
     throw new NullPointerException(); 

    final ExecutorService executor = Executors.newSingleThreadExecutor(PUBLISH_WORK_THREAD_FACTORY); 

    try 
    { 
     executor.execute(() -> { 

      try 
      { 
       if (callback != null) 
       { 
        final ZkWorkItem retval = publishWorkItem(payload); 
        callback.onCompleted(retval); 
       } 
      } 
      catch (final InterruptedException e) 
      { 
       // suppressed 
      } 
      catch (final Exception e) 
      { 
       LOGGER.error("Unhandled exception", e); 

       if (callback != null) 
        callback.onError(e); 
      } 
     }); 
    } 
    finally 
    { 
     executor.shutdown(); 
    } 
} 

문제는 내가 각 비동기 요청에 대한 새로운 ExecutorService를 Executors.newSingleThreadExecutor을 만드는 대신 고정 스레드 풀을 사용하고 있다는 점이다. 그 이유는 publishWorkItem(payload) 메서드가 이 끝나기를 기다리기 때문에 실행중인 스레드를 차단하는 CountDownLatch#await()을 사용한다는 것입니다. 이렇게하면 고정 된 크기의 풀이 빨리 소모 될 수 있습니다. publishWorkItem(payload)

final CountDownLatch latch = new CountDownLatch(1); 

     zkClient.exists(pathToWatch, new Watcher() 
     { 
      @Override 
      public void process(final WatchedEvent event) 
      { 
       try 
       { 
        extractAndDelete(baos, event.getPath()); 
       } 
       catch (final Exception e) 
       { 
        LOGGER.error("Unable to perform cleanup", e); 
       } 
       finally 
       { 
        latch.countDown(); 
       } 
      } 
     }, true); 

     ------ THIS IS THE PROBLEM (Blocks current thread) ------ 
     latch.await(); 

그래서 내 질문은의

간체 코드 : 문제의 유형이 더 나은 방법을 제공합니다.

응용 프로그램의 프로필을 작성했는데 성능에 문제가없는 것으로 알고 많은 스레드가 생성되었습니다.

+0

사이드 노트 : 간단한 한 줄 짜기로 null 던지기를 대체 할 수 있습니다 :'Objects.requireNonNull (theObject, "theObject는 null이 아니어야합니다")' – GhostCat

+1

당신이 무엇인지 분명하지 않기 때문에 당신에게 조언하기가 어렵습니다. 여기에서 성취하려고 노력합니다. 또한 다소 중복 된 현재 태그 중 하나 이상을 제거하고 [zookeeper]를 추가하는 것이 유용 할 수 있습니다. ZK로하려는 사람에게 익숙하지 않은 공통 패턴이있을 수 있으므로 ZK 개시자가 아닙니다. –

답변

0

ExecutorService.newCachedThreadPool()을 사용하지 않는 이유는 무엇입니까? javadoc에 따르면

, 그것은

이 풀은 일반적으로 단기의 비동기 태스크를 다수 실행하는 프로그램의 성능을 향상됩니다 사용 사례에 맞는 ... 이전에 건설 재사용 할 스레드를 사용할 수

경우

publishWorkItem()의 각 호출에서 새 단일 스레드 풀을 만드는 대신 캐시 된 스레드 풀을 한 번 만들고 모든 쿼리에 사용합니다. 스레드 수는 Integer.MAX_VALUE으로 제한되므로 고정 된 스레드 풀과 같이 제한되지는 않지만 전반적으로 스레드를 적게 생성해야합니다.

+0

이것이 결국 내가 한 일입니다. – Greg