我有一個JTabbedpane面板,在每個選項卡中可以設置參數以執行查詢。當一個查詢忙於從數據庫中檢索他的數據時,您可以打開一個新選項卡來設置新的參數。爲避免數據庫過載,只能同時執行一個查詢。但是當你點擊執行時,程序必須記住哪些查詢以正確的順序執行。在執行過程中,顯示一個加載器圖標,並且可能不會凍結GUI,因爲有一個停止按鈕可以單擊以停止執行。
我使用了一個swingworker來避免GUI在執行查詢時被阻塞,並且工作正常。但是現在我想阻止下一個查詢在前一個查詢完成之前啓動。在模型中,共同爲整個面板,我初始化一個信號:private final Semaphore semaphore = new Semaphore(1, true);
這是開始的SwingWorker的代碼(我已經添加的println命令來查看相應地開始,停止或完成)依次使用信號量運行swingworkers
private void doStoredQuery() {
try {
semaphore.acquire();
System.out.println(queryName + "started");
worker.execute();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
,這是我的SwingWorker(initializeWorker()從主類的構造函數調用):
private SwingWorker<StoredQueryDataModel, Integer> initializeWorker() {
worker = new SwingWorker<StoredQueryDataModel, Integer>() {
@Override
protected StoredQueryDataModel doInBackground() throws Exception {
try {
StoredQueryDataModel dataModel = null;
publish(0);
try {
dataModel = new StoredQueryDataModel(queryRunner, ldbName, queryName, params);
} catch (S9SQLException e) {
//
} catch (Throwable e) {
showErrorMessage(e);
}
return dataModel;
}
finally {
semaphore.release();
System.out.println(queryName + "finished");
}
}
@Override
protected void process(List<Integer> chunks) {
//ignore chunks, just reload loader icon
panel.repaint();
}
@Override
protected void done() {
String error;
try {
result = get();
error = null;
} catch (Exception e) {
error = e.getMessage();
}
if(result == null) {
semaphore.release();
System.out.println(queryName + " stopped");
}
if(error == null) {
// process result
}
else {
showErrorMessage(new Throwable(error));
}
}
};
return worker;
}
我試圖把獲取和釋放在代碼的其他位置,但似乎沒有任何工作。我在Swingworker和sempahores bot很新...有人可以幫忙嗎?