Consider a Swing application with a JList or JTable when the choice modifies the launch of SwingWorker and loads related data from the database and updates the user interface. This works great and the user interface is responsive.
But if the user quickly changes the selected row (holding the up / down key), I want to be sure that the last selected row is the one that was loaded last, and I also do not want to query the database in vain. So what I want is a single-threaded executor with a LIFO queue of size = 1. Thus, sending a task to it deletes all previous tasks set and forces it to perform no more than 1 task at a time and has no more than 1 task waiting to be completed.
I could not find anything like it in java.util.concurrent, so I wrote my own Executor. Was I right about this, or am I missing something from the parallel package? Is the solution acceptable or are there better ways to achieve what I want?
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);
}
}
And here is an example showing how it can be used:
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());
}
}
});
Uhlen source
share