Showing posts with label Executor Framework. Show all posts
Showing posts with label Executor Framework. Show all posts

Tuesday, March 3, 2020

Interview in Sapient on Executor Framework - Part - II

Hi Friends,

In this post I'm extending previous post  Interview in Sapient on Executor framework interview questions asked in Sapient.

Hope these questions help everybody in their interview preparation.


You all can also read questions-answers from my other posts:





Question 1:

What is the difference between submit() and execute() methods in executor framework?


Answer:

There are multiple differences between submit() and execute() methods in executor framework which are described below:


  • execute() method is declared in Executor interface. While submit() method is declared in ExecutorService interface which extends Executor interface.
  • execute() method can take only Runnable object as parameter. While submit() has 3 overloaded forms which accept Runnable , Callable , Runnable and result type.
  • execute() method returns void. While all forms of submit() method returns Future instance.

Note: A thread can be created only with Runnable instance.



Question 2:

When result will be returned by Future.get() , when we call submit(Runnable instance)?

Answer:

As we know, run() method in Runnable doesn't return anything. So, Future instance in this case will not hold any result and calling get() on Future object will return null upon successful completion.



Question 3:

How to execute a collection of tasks at once in Executor Framework?

Answer:

We can call invokeAll() method from ExecutorService passing a collection of all tasks in it.

Syntax:

List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)



Question 4:

Describe the purpose and use case of Fork/Join framework.

Answer:

The fork/join framework allows parallelizing recursive algorithms. The main problem with parallelizing recursive algorithms with ThreadPoolExecutor is that we may quickly run out of threads because each recursive step requires its own thread.

The Fork/Join framework entry point is ForkJoinPool class which is an implementation of ExecutorService. It implements the work-stealing algorithm , where idle threads try to steal work from busy threads.
This allows to spread the calculations among  various threads and make progress while using fewer threads than it would require with a usual thread pool.


Question 5:

How many ways are there to create a thread and run it?

Answer:

There are 3 ways to create and run threads in java:

First way:

Thread t = new Thread(() -> System.out.println("Running thread using lambda expression"));
t.start();



Second way:

Thread t = new Thread(new Runnable(){

    public void run(){

        System.out.println("Running thread using Runnable instance");
    }

});

t.start();



Third way:

Thread t = new Thread(){

    public void run(){

        System.out.println("Running thread using anonymous class");
    }
}

t.start();



Question 6:

What are the available implementations of ExecutorService interface?

Answer:

There are mainly 3 implementations of ExecutorService interface.


  • ThreadPoolExecutor
  • ScheduledThreadPoolExecutor
  • ForkJoinPool



Question 7:

What special guarantee does the Java Memory Model hold for final fields of a class?

Answer:

Java Memory Model guarantees that final fields of the class will be initialized before any thread gets hold of the object.
Without this guarantee, an object of the class may be published i.e. become visible to other threads before all the fields of this object are initialized due to reorderings or other optimizations. This could cause racy access to these fields.



That's all for this post.

Thanks for reading!!


Monday, March 2, 2020

Interview in Sapient on Executor Framework

Hi Friends,

In this post, I'm sharing the Executor framework interview questions asked in Sapient.

You can also go through the questions-answers in other interviews as well:





Question 1:

Why to use executor framework?

Answer:

Executor framework is used to decouple command submission from command execution.


Question 2:

What is executor framework?

Answer:

Executor framework gives us the ability to create and manage threads. It provides below functionalities:


  • Creating Thread
  • Managing Thread
  • Task submission and execution



Question 3:

What interfaces are there in executor framework?


Answer:

There are multiple interfaces in executor framework. Let me describe a few of them here:

Executor: A simple interface that contains a method called execute() to launch a task specified by a Runnable object.

ExecutorService: A sub-interface of Executor that adds functionality to manage the lifecycle of the tasks. It also provides a submit() method whose overloaded versions can accept a Runnable as well as a Callable object. Callable objects are similar to Runnable  except that the task specified by a Callable object can also return a value.

ScheduledExecutorService: A sub-interface of ExecutorService. It adds functionality to schedule the execution of tasks.



Question 4:

What are the classes in Executor framework?

Answer:

Executors:  It contains factory methods for creating different kinds of executor services.



Question 5:

How to use Executor Service?

Answer:

import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;

public class ExecutorExample{

    public static void main(String[] args){

        ExecutorService exeService = Executors.newSingleThreadExecutor();

        Runnable runnable = () -> {

             System.out.println("Executing thread");
        }

        exeService.submit(runnable);

    }


}

Note: In the above code, Executor service uses only one thread for executing tasks. If that thread is busy, then the task will wait in a queue until the thread is free to execute it.
This program never exits, because the executor service keeps listening for new tasks until we shut it down explicitly.


Question 6:

How to shutdown the executor service?

Answer:

We can shutdown the executor service using 2 methods:

shutdown(): When shutdown() method is called on an executor service, it stops accepting new tasks, waits for previously submitted tasks to execute and then terminates the executor.


shutdownNow(): This method interrupts the running task and shuts down the executor immediately.





Question 7:

How to schedule a task using Executor framework?


Answer:

ScheduledExecutorService exeService = Executors.newScheduledThreadPool(1);

Runnable task= () ->{


    System.out.println("Executing thread");
}

exeService.schedule(task, 5, TimeUnit.SECONDS);

exeService.shutdown();


Note: If we want to execute the task periodically, we can do so by:

exeService.scheduleAtFixedRate(task, 0, 2, TimeUnit.SECONDS);





Question 8:

Why should we  use ThreadPoolExecutor, when we have Executor Framework?

Answer:

Source code of Executors.newFixedThreadPool() is:

public static ExecutorService newFixedThreadPool(int nThreads){

    return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new                                                                    LinkedBlockingQueue<Runnable>());

}

This method uses ThreadPoolExecutor class with default configuration as is seen in above code. Now there are scenarios where default configuration is not suitable say instead of LinkedBlockingQueue, a priority queue needs to be used etc.
In such cases, caller can directly work on underlying ThreadPoolExecutor by instantiating it and passing desired configuration to it.

Note: One advantage of using ThreadPoolExecutor is that we can handle RejectedExecutionException using ThreadPoolExecutor.DiscardPolicy().


Question 9:

How the number of threads contained in thread pool is determined when using ThreadPoolExecutor?

Answer:

The number of threads in the thread pool is determined by these variables:


  • corePoolSize
  • maximumPoolSize


If less than corePoolSize threads are created in the thread pool when a task is delegated to the thread pool, then a new thread is  created, even  if idle threads exist in the pool.


If the internal queue of tasks is full and corePoolSize threads or more are running, but less than the maximumPoolSize threads are running, then a new thread is created to execute the task.

 

Question 10:

What is the difference between Fixed thread pool and cached thread pool?

Answer:

Fixed thread pool allows to create a pool with fixed number of threads.
Cached thread pool creates any number of threads depending upon the tasks provided. If number of tasks passed to ExecutorService is large, then cached thread pool creates too many threads and may increase overhead of the system.


That's all for this post.
I'll write Part - II very soon.

Thanks for reading!!







CAP Theorem and external configuration in microservices

 Hi friends, In this post, I will explain about CAP Theorem and setting external configurations in microservices. Question 1: What is CAP Th...