Saturday, May 22, 2021

Multithreading: Executor Service

Java executor framework is used to run Runnable objects without creating new threads each time, rather it uses already created threads from the pool. Creating a thread is a very expensive process from a memory perspective, so it’s always a good idea to reuse the threads already created. In java.util.concurrent package there are three interfaces

  • Executor: Used to submit a new task
  • ExecutorService: A subinterface of Executor interface that submit new tasks and method to produce Future as a result of asynchronous operation
  • ScheduledExecutorService: A subinterface of ExecutorService, to run tasks periodically or after a given delay

 Executor can be created using factory Executors class as follows

  • ExecutorService es = Executors.newSingleThreadExecutor()
    • Executes tasks in sequential manner
    • If a thread dies due to some exception, a new thread will be created
  • ExecutorService es = Executors.newFixedThreadPool(int n)
    • Creates thread pool of size n to execute n tasks simultaneously
    • Remaining tasks are stored in LinkedBlockingQueue
    • LinkedBlockingQueue is used to ensure same task is not accessed by 2 or more threads
  • ExecutorService es = Executors.newCachedThreadPool()
    • Creates a thread on demand and kills thread after 60 seconds of idle time
    • If tasks are taking long to execute, there is possibility of performance drop
  • ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor()
    • Creates a single thread scheduled executor service
  • ScheduledExecutorService ses =Executors.newScheduledThreadPool(int i)
    • Creates a scheduled executor service with thread pool of size int i
  • scheduleAtFixedRate and scheduleWithFixedDelay are 2 methods for scheduled executor service; both methods have same signature “(Runnable command, long initialDelay, long period, TimeUnit unit)”
  • The interpretation of “long intialDelay” for both methods is different; scheduleAtFixedRate will execute the task at each fixed interval irrespective of when earlier task is completed and scheduleWithFixedDelay will wait for initialDelay to start next task once first task is completed, for example 

scheduleAtFixedRate

scheduleWithFixedDelay

00:00: Start making coffee

00:00: Start making coffee

00:10: Finish making coffee

00:10: Finish making coffee

01:00: Start making coffee

01:10: Start making coffee

01:10: Finish making coffee

01:20: Finish making coffee

02:00: Start making coffee

02:20: Start making coffee

02:10: Finish making coffee

02:30: Finish making coffee

  • Following are the ways to delegate tasks to ExexcutorService

execute(Runnable)

Returns void, cannot access the result

submit(Runnable)

Returns Future object, null if thread finished. There is no way to know if thread is finished because of an exception, but not the case with Callable (below) as it returns a value from the method.

submit(Callable)

Callable.call returns ‘Object’ which can be accessed using future.get; call() can also throw exception

invokeAny(List<Callable>)

Takes list of Callable tasks, does not return future, instead returns result of one of the Callable tasks which is finished, remaining Callable tasks are cancelled

invokeAll(List<Callable>)

Takes list of Callable, returns list of Future objects 

  • You can use future.cancel() to cancel a task which is submitted. It will get cancelled only if it is not yet started
  • To shutdown executorService and terminate all the threads associated, you can call executorService.shutdown(). It might not shutdown immediately but it will stop accepting new tasks. Once all threads are finished, it will shutdown.
  • To shutdown executorService immediately, you can call executorService.shutdownNow(). It will attempt (no guarantee) to stop all executing tasks and ignore which are not yet started. executorService.awaitTermination will block the thread calling it, until executorService shutdown or till timeout specified

No comments:

SpringBoot: Features: SpringApplication

Below are a few SpringBoot features corresponding to SpringApplication StartUp Logging ·          To add additional logging during startup...