Envisager une application Swing avec un JList ou JTable, lorsque la sélection change, un SwingWorker est démarré et charge les données connexes à partir de la base de données et met à jour l'interface utilisateur. Cela fonctionne bien et l'interface utilisateur est réactive."Single LIFO Executor"/SwingWorker
Mais si l'utilisateur change rapidement la ligne sélectionnée (en maintenant la touche enfoncée), je veux être sûr que la dernière ligne sélectionnée est celle qui est chargée en dernier, et aussi je ne veux pas interroger la BD en vain. Donc ce que je veux, c'est un Executor à un seul thread avec une file d'attente LIFO de taille = 1. Ainsi, l'envoi d'une tâche supprime toutes les tâches soumises précédemment et la fait exécuter au plus une tâche à la fois et avoir au plus une tâche en attente d'exécution.
Je n'ai rien trouvé de pareil dans java.util.concurrent alors j'ai écrit mon propre Executor. Avais-je raison de le faire ou ai-je oublié quelque chose dans le paquet concurrent? La solution est-elle acceptable ou existe-t-il de meilleurs moyens de réaliser ce que je veux?
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);
}
}
Et voici un exemple montrant comment il pourrait être utilisé:
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());
}
}
});