JList または JTable を使用する Swing アプリケーションを考えてみましょう。選択が変更されると、SwingWorker が開始され、データベースから関連データがロードされ、UI が更新されます。これは正常に機能し、UI はレスポンシブです。
しかし、ユーザーが選択した行をすばやく変更している場合 (キーアップ/ダウンを押したまま)、最後に選択した行が最後にロードされた行であることを確認したいと思います。また、無駄に DB にクエリを実行したくありません。したがって、サイズが 1 の LIFO キューを持つシングル スレッドのエグゼキュータが必要です。そのため、タスクをサブミットすると、以前にサブミットされたタスクが削除され、一度に最大 1 つのタスクが実行され、最大 1 つのタスクが実行待ちになります。
java.util.concurrent でこのようなものを見つけることができなかったので、独自の Executor を作成しました。私はそれを正しかったのですか、それとも並行パッケージから何かが欠けていますか? 解決策は受け入れられますか、それとも私が望むものを達成するためのより良い方法はありますか?
public class SingleLIFOExecutor implements Executor
{
private final ThreadPoolExecutor executor;
private Runnable lastCommand;
public SingleLIFOExecutor()
{
executor = new ThreadPoolExecutor(0, 1, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));
}
@Override
public void execute(Runnable command)
{
executor.remove(lastCommand);
lastCommand = command;
executor.execute(command);
}
}
そして、これがどのように使用できるかを示す例です:
final Executor executor = new SingleLIFOExecutor();
JList jList = createMyList();
jList.addListSelectionListener(new ListSelectionListener()
{
@Override
public void valueChanged(ListSelectionEvent e)
{
if (!e.getValueIsAdjusting())
{
executor.execute(new MyWorker());
}
}
});