2016-07-20 2 views
1

현재 스프링 부트를 사용하여 웹 응용 프로그램을 개발 중이며 서비스 계층에 문제가 있습니다.스프링 부트 서비스에서 제한된 수의 스레드를 실행하십시오.

내 서비스 계층에 무거운 방법이 있습니다. 여러 사용자가 동일한 서비스를 호출하면 메모리가 부족하여 응용 프로그램이 중지됩니다. 그래서 그 방법의 병렬 실행 스레드 수를 제한하고 싶습니다. 지금까지 나는 동기화 방법을 사용하여 나와 있습니다. 그러나 단일 스레드 메소드로 제한됩니다.

@Service 
public class DocumentService{ 

    private synchronized void doReplacement(){ 
     //should have limited no of multi threads (eg. 3) 
    } 

    private void normalMethod(){ 
     //no restrictions 
    } 

} 

이 작업을 수행하려면 어떻게해야합니까? 어떤 도움을 주시면 감사하겠습니다.

+0

: 당신은 아직도 스레드와 함께 가고 싶은 경우

, 내 제안은 ExecutorService를를 사용하는 것 : //stackoverflow.com/questions/16591147/lock-a-runnable-until-finished) 또는 [this] (http://stackoverflow.com/questions/21124879/how-do-i-make-java-wait- for-a-method-to-continue-before-continue) 도움이 될 것입니다 ... –

+1

그럼 Executors를 생성하고 사용하여 스레드 수를 제한 할 수 있습니다. BTW 첫 번째 메모리 누수가 있는지 확인하십시오 ...... –

+0

스프링 프레임 워크는 서비스 계층에서 모든 스레딩을 작성하므로 스레드를 수동으로 처리 할 수 ​​없습니다. 방법이 있습니까 ?? – Ravindu

답변

1

동시에 메서드를 실행할 수있는 스레드 수보다 일종의 요청 조절 (즉, 초당 요청 수)을 사용하는 것이 더 나을 수도 있습니다. 예를 들어 Guava's RateLimiter을 직접 사용하거나 이벤트 adding declarative support for with Spring's AOP을 사용할 수 있습니다. 실행시 아니라면 .... 어쩌면 [이] (방법 HTTP를 수동 잠금 장치를 적용

@Service 
public class DocumentService { 

    private final ExecutorService executor; 

    @Autowired 
    public DocumentService(
     @Value("${some.config.property}") int maxConcurrentThreads) { 
     // will allow only the given number of threads 
     executor = Executors.newFixedThreadPool(maxConcurrentThreads); 
    } 

    private void doReplacementWithLimitedConcurrency(String s, int i){ 
     Future<?> future = executor.submit(() -> doReplacement(s, i)); 
     future.get(); // will block until a thread picks up the task 
         // and finishes executing doReplacement 
    } 

    private void doReplacement(String s, int i){ 
    } 

    // other methods 

    @PreDestroy 
    public void performThreadPoolCleanup() throws Exception { 
     executor.shutdown(); 
     executor.awaitTermination(10, TimeUnit.SECONDS); 
     executor.shutdownNow(); 
    } 
} 
+0

여기 문제는 doReplacement (String s, Int i)와 같은 doReplacement에서 몇 가지 인수를 전달해야한다는 것입니다. 제출 가능한 호출 가능 인수를 허용하지 않습니다. 어떻게 해결할 수 있습니까? – Ravindu

+0

감사합니다. Milos, DoReplacement 클래스를 만들고 Callable로 구현했습니다. 생성자를 사용하여 값을 전달했습니다. – Ravindu

+1

람다를 사용하는 것보다 덜 효율적이지만 그게 효과가 있습니다. 아직 Java 7을 사용하고 있지 않다면, 완벽하게 이해할 수 있습니다 :) –

관련 문제