2016-10-11 42 views
1

我不得不面對一個蹩腳的庫,在我的Spring啓動項目(一個REST風格的Web服務),使用單身和靜態類,所以當多個客戶端使用RestController我有一個同步問題:春季開機同步訪問靜態類

我在同步方法中封裝了庫的用法,但沒用,併發用法不斷髮生......我不明白爲什麼以及如何實現同步行爲。

感謝您的幫助!

---解決---

由於@Anthony建議我使用的ReentrantLock,你可以看到下面的執行情況。

由於日誌庫問題(另一個問題)而導致不能打印錯誤消息的方法中違反了斷言的第二個問題generateModel 。

問題解決了,謝謝。

--- ---代碼

public class ModelingLocker { 
private static final ReentrantLock reentrantLock = new ReentrantLock(); 

private String modeling; 
private File out; 

public ModelingLocker(String modeling, File out) { 
    this.modeling = modeling; 
    this.out = out; 
} 

public File synchroModeling() throws EngineException { 
    reentrantLock.lock(); 
    System.out.println(reentrantLock); 
    System.out.println(System.identityHashCode(reentrantLock)); 
    try { 
     long id = Thread.currentThread().getId(); 
     System.out.println(String.format("--start--> Thread=%d %s", id, modeling)); 
     ModelingEngine.generateModel(out); 
     System.out.println(String.format("<--end-- Thread=%d %s", id, modeling)); 
    } finally { 
     reentrantLock.unlock(); 
    } 
    return out; 
} 
} 

我用它內部的

@Service 
public class ModelingService { 
//... 
    @Async 
    public Future<Void> model(File file, String message) { 
     ModelingLocker modelingLocker = new ModelingLocker(message, file); 
     if (isWellFormed(modelingLocker.synchroModeling()) { 
     //... 
     } 
     return new AsyncResult<>(null); 
    } 

//... 
} 

這項服務是一個休息控制器內自動連接,我需要@Async因爲generateModel方法一個長期的任務,我必須回答201客戶端

+0

你在哪裏放置了同步方法?什麼對象被鎖定?如果不同的線程鎖定包含同步方法的類的不同實例,則它們不會彼此等待。 – Jesper

+0

可重入鎖應該是正確的解決方案,但不起作用... –

+0

那麼你很可能以錯誤的方式使用它。顯示你所嘗試的內容,以便人們可以評論你是否正確使用它。 – Jesper

回答

2

你試過使用可重入鎖嗎? 你可能想看看這個鏈接,例如用法 http://javarevisited.blogspot.com/2013/03/reentrantlock-example-in-java-synchronized-difference-vs-lock.html

+0

我試過了。不起作用! 我用一個靜態初始化的ReentrantLock將邏輯封裝到一個類中,但是這個對象在不同的​​線程中是不同的......所以我不明白爲什麼我有靜態庫的問題! –

+0

對不起,我錯了:他們是同一個對象,但鎖定方法不鎖! –

0

只是同步應該由一個線程訪問的方法。

+0

我試過了。不起作用! –