2016-07-20 38 views
1

我目前正在開發一個使用spring啓動的web應用程序,並且在服務層有問題。在Spring Boot服務上運行有限數量的線程

我在我的服務層有一個沉重的方法。如果多個用戶調用相同的服務,則應用程序由於內存不足而停止。所以我想限制只有該方法的並行運行線程的數量。到目前爲止,我已經在該方法中使用了同步。但它會將其限制爲單線程方法。

@Service 
public class DocumentService{ 

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

    private void normalMethod(){ 
     //no restrictions 
    } 

} 

我能做些什麼來實現這個任務。任何幫助,將不勝感激。

+0

執行申請時手動鎖定的方法,如果沒有....也許[這](HTTP ://stackoverflow.com/questions/16591147/lock-a-runnable-until-finished)或[this](http://stackoverflow.com/questions/21124879/how-do-i-make-java-wait-爲方法來完成之前繼續)可能會幫助... –

+1

那麼你可以創建和使用執行程序來限制線程數。順便說一句,檢查是否沒有內存泄漏...... –

+0

由於spring框架創建服務層中的所有線程,我無法手動處理線程。有沒有辦法? – Ravindu

回答

1

與使用某種請求限制(即每秒請求數)相比,使用某種請求限制可能會比同時執行方法的線程數多。例如直接使用Guava's RateLimiter,或者可能使用事件adding declarative support for with Spring's AOP

如果你還想去與線程,我的建議是使用一個ExecutorService:

@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

感謝米洛斯,我創建了一個類作爲DoReplacement並由Callable實現。並使用構造函數將值傳遞給它。 – Ravindu

+1

也可以工作,雖然它比使用lambda有點低效。除非你仍然使用Java 7,否則它會變得非常有意義:) –