不能为任务排队的Java执行器



我需要一个Java执行器,如果有其他任务正在处理,它会拒绝任务。我猜这是不可能得到操纵工作队列的大小。

有人可能会奇怪为什么我需要一个具有这种特征的遗嘱执行人。我需要能够轻松更改策略并允许非零队列大小。

任何想法?

使用ThreadPoolExecutor和SynchronousQueue(从这个答案复制来的)

它似乎工作:

import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.Semaphore;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class SingleTaskExecutor {
public static void main(String[] args) {
    try {
        new SingleTaskExecutor().runTest();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
public void runTest() throws Exception {
    ThreadPoolExecutor tp = new ThreadPoolExecutor(1, 1,
            60L, TimeUnit.SECONDS,
            new SynchronousQueue<Runnable>());
    tp.setRejectedExecutionHandler(new RejectedTaskHandler());
    final Semaphore oneTaskDone = new Semaphore(0);
    tp.execute(new Runnable() {
        @Override public void run() { 
            System.out.println("Sleeping");
            try { Thread.sleep(300); } catch (Exception e) { e.printStackTrace();} 
            System.out.println("Done sleeping");
            oneTaskDone.release();
        }
    });
    tp.execute(new Runnable() {
        @Override public void run() { System.out.println("Never happends"); }
        @Override public String toString() { return "Rejected Runnable"; }
    });
    oneTaskDone.acquire();
    tp.execute(new Runnable() {
        @Override public void run() { System.out.println("Running"); }
    });
    tp.shutdown();
    tp.awaitTermination(100, TimeUnit.MILLISECONDS);
    System.out.println("Finished");
}
static class RejectedTaskHandler implements RejectedExecutionHandler {
    @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        System.out.println("Task rejected: " + r);
    }
}
}

From your statement

每次一个。此外,如果执行正在等待,它应该拒绝其他提交。

我的结论是

一次只处理一个任务,并在当前任务处理过程中拒绝其他任务是您的要求。在这种情况下,下面的代码应该完成这项工作。

BlockingQueue queue = new ArrayBlockingQueue(1);
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 10, TimeUnit.SECONDS, queue, 
ThreadPoolExecutor.DiscardPolicy);
// Submit Your callable task
executor.submit(yourCallableTask);

使用ThreadPoolExecutor。在将任务提交给执行器之前,调用getActiveCount()并检查它是否等于池大小(意味着所有线程都是活动的)。如果有,就不要提交任务。

最新更新