How can I make ThreadPoolExecutor command wait if there's too much data it needs to work on?

后端 未结 4 1422
我在风中等你
我在风中等你 2020-12-14 04:45

I am getting data from a queue server and I need to process it and send an acknowledgement. Something like this:

while (true) {
    queueserver.get.data
             


        
4条回答
  •  南方客
    南方客 (楼主)
    2020-12-14 04:49

    What about having a blockingPool which will not execute more than 200 tasks and wait for a task to complete before submitting 201 task. I've achieved it using semaphore in my application. You can also change the limit by passing the value to its constructor.

    Only difference here from @Gray answer is that rarely any task will get rejected in this case. Semaphore will make any 201 task to wait unless a other task gets over. Nevertheless, we have rejection handler to re-submit that task to executor in case of any rejection.

    private class BlockingPool extends ThreadPoolExecutor {
        private final Semaphore semaphore;      
        public BlockingPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, int tasksAllowedInThreads){    
            super(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue,new RejectedExecutionHandler() {
                @Override
                public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                    executor.execute(r);
                }
            });
            semaphore = new Semaphore(tasksAllowedInThreads);
        }
    
        @Override
        public void execute(Runnable task){
            boolean acquired = false;
            do{
                try{
                    semaphore.acquire();
                    acquired = true;
                } catch (final InterruptedException e){
                    // log
                }
            } while (!acquired); // run in loop to handle InterruptedException
            try{
                super.execute(task);
            } catch (final RejectedExecutionException e){
                System.out.println("Task Rejected");
                semaphore.release();
                throw e;
            }
        }    
    
        @Override
        protected void afterExecute(Runnable r, Throwable t){
            super.afterExecute(r, t);
            if (t != null){
                t.printStackTrace();
            }
            semaphore.release();
        }
    }
    

    Does this make sense!

提交回复
热议问题