Java executor with no ability to queue tasks

烂漫一生 提交于 2019-12-10 20:52:22

问题


I need an Java executor that rejects tasks if some other task is processing. I guess it's not possible to get manipulating the working queue size.

Someone might wonder why I need an executor with such characteristic in the first place. I need an ability to easily change the policy and allow non-zero queue size.

Any ideas?


回答1:


Use a ThreadPoolExecutor with a SynchronousQueue (copied from this answer).

It appears to work:

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);
    }

}

}



回答2:


From your statement

One at a given time. Also, if execution is pending it should reject other submissions.

I am concluding that

Processing only one task at a time and rejecting other tasks during current task processing is your requirement. In this case, below code should do the job.

BlockingQueue queue = new ArrayBlockingQueue(1);
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 10, TimeUnit.SECONDS, queue, 
ThreadPoolExecutor.DiscardPolicy);

// Submit Your callable task
executor.submit(yourCallableTask);



回答3:


Use ThreadPoolExecutor. Before submiting task to executor call getActiveCount() and check if it equals pool size (meaning all threads are active). If it does, just don't submit the task.



来源:https://stackoverflow.com/questions/24692027/java-executor-with-no-ability-to-queue-tasks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!