1

인바운드 큐에서 소비하고 일부 아웃 바운드 대기열 (이 서비스에서 생성 된 다른 스레드가 메시지를 선택하여 대상으로 전송)에 대한 일부 서비스를 제공합니다.Java에서 폴링 차단 사용자를 실행하는 방법은 무엇입니까?

현재 코드에서 볼 수 있듯이 두 개의 일반 Thread을 사용하지만 일반적으로 더 이상 사용하지 말고 대신 ExecutorService과 같은 상위 수준의 추상화를 사용해야합니다.

제 경우에 의미가 있습니까? 더 구체적으로 말하자면 ->

  • 코드를 줄일 수 있습니까?
  • 오류 발생시 코드를보다 강력하게 만드시겠습니까?
  • 더 부드러운 스레드 종료가 가능합니까? (테스트를 실행할 때 유용합니다)

여기에 중요한 것이 있습니까?

// called on service startup 
private void init() { 
    // prepare everything here 
    startInboundWorkerThread(); 
    startOutboundTransporterWorkerThread(); 
} 

private void startInboundWorkerThread() { 
    InboundWorkerThread runnable = injector.getInstance(InboundWorkerThread.class); 
    inboundWorkerThread = new Thread(runnable, ownServiceIdentifier); 
    inboundWorkerThread.start(); 
} 

// this is the Runnable for the InboundWorkerThread 
// the runnable for the transporter thread looks almost the same 
@Override 
public void run() {  
    while (true) { 
     InboundMessage message = null; 
     TransactionStatus transaction = null; 

     try { 
      try { 
       transaction = txManager.getTransaction(new DefaultTransactionDefinition()); 
      } catch (Exception ex) { 
       // logging 
       break; 
      } 

      // blocking consumer 
      message = repository.takeOrdered(template, MESSAGE_POLL_TIMEOUT_MILLIS); 
      if (message != null) {     
       handleMessage(message); 
       commitTransaction(message, transaction); 
      } else { 
       commitTransaction(transaction); 
      } 
     } catch (Exception e) { 
      // logging 
      rollback(transaction); 
     } catch (Throwable e) { 
      // logging 
      rollback(transaction); 
      throw e; 
     } 

     if (Thread.interrupted()) { 
      // logging 
      break; 
     } 
    } 

    // logging 
} 

// called when service is shutdown 
// both inbound worker thread and transporter worker thread must be terminated 
private void interruptAndJoinWorkerThread(final Thread workerThread) { 
    if (workerThread != null && workerThread.isAlive()) { 
     workerThread.interrupt(); 

     try { 
      workerThread.join(TimeUnit.SECONDS.toMillis(1)); 
     } catch (InterruptedException e) { 
      // logging 
     } 
    } 
} 

답변

0

스레드 풀을 사용하여 나를위한 주요 이점은 ThreadPool에서 스레드의 단일 독립적 보통 짧은 작업에서 작업하고 더 나은 추상화를 구성에서 온다 (java.util.concurrent의에서 다른 클래스를 메이비) s 개인 Worker s. 때로는 그 사람들에게 더 직접적인 접근을 원할 수도 있습니다. 여전히 실행 중인지 알아내는 것이 좋습니다. 그러나 대체로 더 나은 것이 있습니다. 작업 중심의 방법이 있습니다.

처리 실패에 관해서는, 당신은 특정 작업에 대한 자세한 정보를 기록하기 위해, 너무 좋은 예외 처리를 사용자 정의 UncaughtExceptionHandler와 스레드를 생성하고, 일반적으로, 당신의 Runnable 작업을 제공해야 자신의 ThreadFactory를 제출 할 수 실패한. 차단 된 작업자로 ThreadPool을 채우고 싶지 않으므로 해당 작업을 차단하지 않습니다. 작업이 대기열에 들어가기 전에 차단 작업을 이동하십시오.

보통 shutdownshutdownNowExecutorService으로 제공되며 작업에서 적절한 인터럽트 처리와 함께 원활하게 작업을 종료 할 수 있습니다.