4

In the following class i'm using a SingleThreadPool (which is static) and i've made sure the static thread pool is initialized only once by using a Boolean object and making it synchronized(see init() method).I've made ThreadPoolExecutor static because i want to re-use the same pool across multiple incoming request.

This class has an inner class i.e) Validator which implements callable and returns a boolean.

The overridden submit method, iterates each input and submit the Validator(Task) to the ThreadPoolExecutor.

public class ValidationProcessor implements IValidation {
 //should this be static or singleton
 private static ThreadPoolExecutor executor;    
 private volatile static Boolean initialized= new Boolean(Boolean.FALSE);
 List<Input> inputList;

 public ValidationProcessor(List<Input> inputList) {
      init();
      this.inputList=inputList;
 }

  public static void init() {
        try {
            synchronized (initialized) {
                if (!initialized.booleanValue()) {
                    LOG.debug("Initializing..................thread pool...");
                    final BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(1000);
                    executor = new ThreadPoolExecutor(3, 5, 60, TimeUnit.SECONDS,
                                                      queue);
                    initialized=new Boolean(Boolean.TRUE);
                }
            }
        } catch (Exception e) {
            LOG.error("Exception while initialising the thread pool {} and stack trace {}" , ExceptionUtils.getFullStackTrace(e));
        }
    } 

      public class Validator implements Callable<Boolean> {

            private final Logger LOG = LoggerFactory.getLogger(Validator.class.getName());
            Input input;

            public ValidateNPublishTask(Input input) {
                this.input=input;
            }

            public boolean validate() {
                final Timer validateTimer = new Timer();
                final boolean isValid = Validator.validate(input);//some process
                return isValid;
            }

            @Override
            public Boolean call() throws Exception {
                return validate();
            }

        }

    @Override
        public boolean submit() {
            Boolean consolidatedOutput=new Boolean(Boolean.TRUE);
            List<Future<Boolean>> validationResult = new ArrayList<Future<Boolean>>();
            try {
                for (final Input i : inputs) {  
                    Validator validate = new Validator(input);
                    Future<Boolean> r = getExecutor().submit(validate);
                    validationResult.add(r);
                }
                for (Future<Boolean> fr : validationResult) {
                    if (!fr.get()) {
                       //change consolidatedOutput to false;
                        break; // at-least one failure, return status as failure
                    }
                }
            } catch (InterruptedException | ExecutionException e) {
                LOG.error("Exception while validating the input {} exception {}",  ExceptionUtils.getFullStackTrace(e)});
            }
            return consolidatedOutput;
        }

public static ThreadPoolExecutor getExecutor() {
    return executor;
}
}

The above class is called from another class Processor.java as follows. This Processor is called within a Web-Application.Since, ValidationProcessor is local variable, it is thread safe.

 Public Class Processor {

    public Response process(Input input) {
           List<Input> inputList = load();
           IValidation validateNPublishObj = new ValidationProcessor(inputList);
           emailResponse=validateNPublishObj.submit();
    }

    public List<Input> load() {
          //return list of inputs <Input>
    }

    }

For simplicity sake, i've left some implementation empty like load().

My Question is more from a design perspective.

  1. In my ValidationProcessor class should the ThreadPoolExecutor be static or singleton.

/* sample singleton */

 public class MyThreadPoolExecutor {
        private final ThreadPoolExecutor executor;
        private static MyThreadPoolExecutor threadPoolInstance = null;

        private MyThreadPoolExecutor() {
          executor = new ThreadPoolExecutor(...); 
        }

    static {
        threadPoolInstance = new MyThreadPoolExecutor();
    }

    public static MyThreadPoolExecutor getInstance() {
        return threadPoolInstance;
    }

}
  1. Does it make any difference if the instance variable of singleton rather than static(in the above case). My whole point is to use single thread pool, and i don't want to use/create a new ThreadPool for each incoming request.

Basically i want all my threads to use the same ThreadPoolExecutor and not to create a ThreadPoolExecutor instance everytime, when the instance of ValidationProcessor is created.

P.S: no need to verify the logic inside submit , assume that it compiles and works. Also the ThreadPoolExecutor is not shared across application and is used only in this class for now.

Raghu
  • 1,363
  • 1
  • 23
  • 37
  • What about just `private static ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 5, 60, TimeUnit.SECONDS, new ArrayBlockingQueue(1000));` ? – Fildor Dec 02 '15 at 11:20
  • Agreed. This would avoid the synchronisation. But i would like to go with lazy init. also what is the difference if i have a singleton here instead of a static ThreadPoolExecutor? – Raghu Dec 02 '15 at 11:39
  • Guess, unless i need the ThreadPoolExecutor to be shared across application, it is better to go with the static ThreadPoolExecutor. – Raghu Dec 02 '15 at 13:07
  • @Raghu, I am having the same question, can you please tell me about the singleton approach. – Atul May 14 '20 at 16:34

0 Answers0