javamultithreadingconcurrencyexecutorserviceexecutor

Java executor with no ability to queue tasks


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?


Solution

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