Java &引用;“单一后进先出执行人”摇摆工人
考虑使用JList或JTable的Swing应用程序,当选择更改时,SwingWorker将启动并从数据库加载相关数据并更新UI。这可以很好地工作,用户界面响应迅速 但是,如果用户正在快速更改所选行(按住键向上/向下),我希望确保最后选择的行是最后加载的行,而且我不想徒劳地查询数据库。所以我想要的是一个单线程执行器,其后进先出队列的大小为1。因此,向其提交任务将删除以前提交的任何任务,并使其一次最多执行一个任务,最多有一个任务等待执行 我在java.util.concurrent中找不到类似的东西,所以我编写了自己的执行器。我这样做是对的还是我在并发包中遗漏了什么?解决方案是否可以接受,或者是否有更好的方法实现我的目标Java &引用;“单一后进先出执行人”摇摆工人,java,swing,concurrency,swingworker,executor,Java,Swing,Concurrency,Swingworker,Executor,考虑使用JList或JTable的Swing应用程序,当选择更改时,SwingWorker将启动并从数据库加载相关数据并更新UI。这可以很好地工作,用户界面响应迅速 但是,如果用户正在快速更改所选行(按住键向上/向下),我希望确保最后选择的行是最后加载的行,而且我不想徒劳地查询数据库。所以我想要的是一个单线程执行器,其后进先出队列的大小为1。因此,向其提交任务将删除以前提交的任何任务,并使其一次最多执行一个任务,最多有一个任务等待执行 我在java.util.concurrent中找不到类似的东
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);
}
}
我相信封锁德克是你想要的。它支持堆栈 我的代码中包含的内容:
private transient final ExecutorService threadPool=
new ThreadPoolExecutor(3, 10,10,
TimeUnit.MILLISECONDS,
new LinkedBlockingDeque<Runnable>());
private临时最终执行器服务线程池=
新线程池执行器(3、10、10、,
TimeUnit.ms,
新LinkedBlockingDeque());
LinkedBlockingDeque似乎仍然使用ThreadPoolExecutor的队列
因此,我使用了一个包装器,并将其与ThreadPoolExecutor一起使用:
package util;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
/**
* LIFO BlockingQueue to be used with the ExecutorService.
* @author Daniel
* @param <T>
*/
public class LinkedBlockingStack<T> implements BlockingQueue<T>{
private final LinkedBlockingDeque<T> stack = new LinkedBlockingDeque<T>();
@Override
public T remove() {
return stack.remove();
}
@Override
public T poll() {
return stack.poll();
}
@Override
public T element() {
return stack.element();
}
@Override
public T peek() {
return stack.peek();
}
@Override
public int size() {
return stack.size();
}
@Override
public boolean isEmpty() {
return stack.isEmpty();
}
@Override
public Iterator<T> iterator() {
return stack.iterator();
}
@Override
public Object[] toArray() {
return stack.toArray();
}
@Override
public <S> S[] toArray(final S[] a) {
return stack.toArray(a);
}
@Override
public boolean containsAll(final Collection<?> c) {
return stack.containsAll(c);
}
@Override
public boolean addAll(final Collection<? extends T> c) {
return stack.addAll(c);
}
@Override
public boolean removeAll(final Collection<?> c) {
return stack.removeAll(c);
}
@Override
public boolean retainAll(final Collection<?> c) {
return stack.removeAll(c);
}
@Override
public void clear() {
stack.clear();
}
@Override
public boolean add(final T e) {
return stack.offerFirst(e); //Used offerFirst instead of add.
}
@Override
public boolean offer(final T e) {
return stack.offerFirst(e); //Used offerFirst instead of offer.
}
@Override
public void put(final T e) throws InterruptedException {
stack.put(e);
}
@Override
public boolean offer(final T e, final long timeout, final TimeUnit unit)
throws InterruptedException {
return stack.offerLast(e, timeout, unit);
}
@Override
public T take() throws InterruptedException {
return stack.take();
}
@Override
public T poll(final long timeout, final TimeUnit unit)
throws InterruptedException {
return stack.poll();
}
@Override
public int remainingCapacity() {
return stack.remainingCapacity();
}
@Override
public boolean remove(final Object o) {
return stack.remove(o);
}
@Override
public boolean contains(final Object o) {
return stack.contains(o);
}
@Override
public int drainTo(final Collection<? super T> c) {
return stack.drainTo(c);
}
@Override
public int drainTo(final Collection<? super T> c, final int maxElements) {
return stack.drainTo(c, maxElements);
}
}
package-util;
导入java.util.Collection;
导入java.util.Iterator;
导入java.util.concurrent.BlockingQueue;
导入java.util.concurrent.LinkedBlockingDeque;
导入java.util.concurrent.TimeUnit;
/**
*要与Executor服务一起使用的后进先出阻塞队列。
*@作者丹尼尔
*@param
*/
公共类LinkedBlockingStack实现阻塞队列{
私有最终LinkedBlockingDeque堆栈=新LinkedBlockingDeque();
@凌驾
公共部门不能删除(){
返回stack.remove();
}
@凌驾
公众投票{
返回stack.poll();
}
@凌驾
公共T元素(){
返回stack.element();
}
@凌驾
公共T peek(){
返回stack.peek();
}
@凌驾
公共整数大小(){
返回stack.size();
}
@凌驾
公共布尔值为空(){
返回stack.isEmpty();
}
@凌驾
公共迭代器迭代器(){
返回stack.iterator();
}
@凌驾
公共对象[]toArray(){
返回stack.toArray();
}
@凌驾
公共S[]toArray(最终S[]a){
返回堆栈到阵列(a);
}
@凌驾
公共布尔容器(最终集合c){
返回堆栈。包含所有(c);
}
@凌驾
公共布尔addAll(最终集合c){
返回堆栈。移除所有(c);
}
@凌驾
公共布尔保留(最终集合c){
返回堆栈。移除所有(c);
}
@凌驾
公共空间清除(){
stack.clear();
}
@凌驾
公共布尔加法(最终T e){
return stack.offerFirst(e);//使用offerFirst代替add。
}
@凌驾
公开报价(最终报价){
return stack.offerFirst(e);//使用offerFirst代替offer。
}
@凌驾
公共无效put(最终T e)抛出InterruptedException{
堆栈。放置(e);
}
@凌驾
公共布尔报价(最终TE、最终长超时、最终时间单位)
抛出中断异常{
返回stack.offerLast(e,超时,单位);
}
@凌驾
public T take()抛出InterruptedException{
返回stack.take();
}
@凌驾
公共T轮询(最终长超时,最终时间单位)
抛出中断异常{
返回stack.poll();
}
@凌驾
公共剩余容量(){
返回堆栈。剩余容量();
}
@凌驾
公共布尔删除(最终对象o){
返回堆栈。移除(o);
}
@凌驾
公共布尔包含(最终对象o){
返回堆栈。包含(o);
}
@凌驾
public int drainTo(最终集合这是我实现的解决方案,非常适合我试图解决的问题:)
/**
*“单一后进先出执行人”。
*
*它维护一个任务队列,并且只有一个任务可以同时执行,
*向{@link#execute(Runnable)}提交新任务将放弃以前提交的所有尚未启动的任务。
*/
公共类SingleLIFOExecutor实现Executor
{
私人最终执行人;
私有Runnable命令;
公共SingleLIFOExecutor()
{
executor=新的ThreadPoolExecutor(0,1,0,毫秒,新的ArrayBlockingQueue(1));
}
/**
*@see java.util.concurrent.Executor#execute(java.lang.Runnable)
*/
@凌驾
public void execute(Runnable命令)
{
执行器。删除(lastCommand);
lastCommand=命令;
执行者。执行(命令);
}
}
package util;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
/**
* LIFO BlockingQueue to be used with the ExecutorService.
* @author Daniel
* @param <T>
*/
public class LinkedBlockingStack<T> implements BlockingQueue<T>{
private final LinkedBlockingDeque<T> stack = new LinkedBlockingDeque<T>();
@Override
public T remove() {
return stack.remove();
}
@Override
public T poll() {
return stack.poll();
}
@Override
public T element() {
return stack.element();
}
@Override
public T peek() {
return stack.peek();
}
@Override
public int size() {
return stack.size();
}
@Override
public boolean isEmpty() {
return stack.isEmpty();
}
@Override
public Iterator<T> iterator() {
return stack.iterator();
}
@Override
public Object[] toArray() {
return stack.toArray();
}
@Override
public <S> S[] toArray(final S[] a) {
return stack.toArray(a);
}
@Override
public boolean containsAll(final Collection<?> c) {
return stack.containsAll(c);
}
@Override
public boolean addAll(final Collection<? extends T> c) {
return stack.addAll(c);
}
@Override
public boolean removeAll(final Collection<?> c) {
return stack.removeAll(c);
}
@Override
public boolean retainAll(final Collection<?> c) {
return stack.removeAll(c);
}
@Override
public void clear() {
stack.clear();
}
@Override
public boolean add(final T e) {
return stack.offerFirst(e); //Used offerFirst instead of add.
}
@Override
public boolean offer(final T e) {
return stack.offerFirst(e); //Used offerFirst instead of offer.
}
@Override
public void put(final T e) throws InterruptedException {
stack.put(e);
}
@Override
public boolean offer(final T e, final long timeout, final TimeUnit unit)
throws InterruptedException {
return stack.offerLast(e, timeout, unit);
}
@Override
public T take() throws InterruptedException {
return stack.take();
}
@Override
public T poll(final long timeout, final TimeUnit unit)
throws InterruptedException {
return stack.poll();
}
@Override
public int remainingCapacity() {
return stack.remainingCapacity();
}
@Override
public boolean remove(final Object o) {
return stack.remove(o);
}
@Override
public boolean contains(final Object o) {
return stack.contains(o);
}
@Override
public int drainTo(final Collection<? super T> c) {
return stack.drainTo(c);
}
@Override
public int drainTo(final Collection<? super T> c, final int maxElements) {
return stack.drainTo(c, maxElements);
}
}
/**
* A "Single Last-In-First-Out Executor".
* <p>
* It maintains a queue of <b>one</b> task and only one task may execute simultaneously,
* submitting a new task to {@link #execute(Runnable)} will discard any previous submitted not yet started tasks.
*/
public class SingleLIFOExecutor implements Executor
{
private final ThreadPoolExecutor executor;
private Runnable lastCommand;
public SingleLIFOExecutor()
{
executor = new ThreadPoolExecutor(0, 1, 0, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));
}
/**
* @see java.util.concurrent.Executor#execute(java.lang.Runnable)
*/
@Override
public void execute(Runnable command)
{
executor.remove(lastCommand);
lastCommand = command;
executor.execute(command);
}
}