我不得不面對一個蹩腳的庫,在我的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客戶端
你在哪裏放置了同步方法?什麼對象被鎖定?如果不同的線程鎖定包含同步方法的類的不同實例,則它們不會彼此等待。 – Jesper
可重入鎖應該是正確的解決方案,但不起作用... –
那麼你很可能以錯誤的方式使用它。顯示你所嘗試的內容,以便人們可以評論你是否正確使用它。 – Jesper