JTabbedpane を含むパネルがあり、すべてのタブでパラメーターを設定してクエリを実行できます。1 つのクエリがデータベースからデータを取得するのに忙しいときは、新しいタブを開いて新しいパラメーターを設定することができます。データベースの過負荷を避けるために、一度に実行できるクエリは 1 つだけです。ただし、実行をクリックすると、プログラムはどのクエリを正しい順序で実行するかを覚えておく必要があります。実行中はローダー アイコンが表示され、GUI がフリーズしない場合があります。これは、クリックして実行を停止できる停止ボタンがあるためです。
クエリの実行中に GUI がブロックされるのを避けるために、swingworker を使用しましたが、問題なく動作しました。しかし、前のクエリが完了する前に次のクエリが開始されるのを防ぎたいと思います。パネル全体に共通のモデルで、セマフォを初期化しました。private final Semaphore semaphore = new Semaphore(1, true);
これは、swingworker を開始するコードです (開始、停止、または終了したものを確認するために println コマンドを追加しました)
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 はまったく新しいものです...誰か助けてくれますか?