Sunday, 27 August 2017

Internal implementation of ArrayList in Java

    There are two List interface implementation classes in Collection , i.e ArrayList and LinkedList. The ArrayList is most commonly used Collection class in java. We can discuss about how ArrayList internally works and what are the methods .

     ArrayList internally uses array object to add the elements. In other words, ArrayList is backed by Array data-structure. The array of ArrayList is resizable i.e dynamic in nature.

     Below code is internal implementation or source code of add(), remove(), contains() and size() methods of ArrayList.


package com.pr;

import java.util.Arrays;

public class CustomArrayList {

       private static int DEFAULT_CAPACITY = 10;
       private int size = 0;
       private transient Object[] element = {};
       
       public CustomArrayList () {
             element = new Object[DEFAULT_CAPACITY];
       } 

       public boolean add(Object obj) {
            if (size == element.length) {
                 increaseCapacity();
             }
             element[size++] = obj;
             return true;
       }
 
       public Object get(int index) {
             if (index >= size || index<0) {
                     throw new ArrayIndexOutOfBoundsException();
             }
             return element[index];
       }
 
       public Object remove(int index) {
            if (index < size) {
                   Object obj = element[index];
                   element[index] = null;
                   int temp = index;
                   while (temp < size) {
                         element[temp] = element[temp + 1];
                         element[temp+1] = null;
                         temp++;
                    }
                    size--;
                    return obj;
             } else {
                  throw new ArrayIndexOutOfBoundsException();
             }
       }
 
       public boolean contains(Object obj) {
              boolean flag = false;
              if (obj == null) {
                   for (int i = 0; i<size; i++) {
                        if (element[i] == null) {
                             flag = true;
                        }
                    }
                } else {
                      for (int i = 0; i<size; i++) {
                           if (obj.equals(element[i])) {
                                flag = true;
                           }
                      }
                }
                return flag;
        } 
 
        private void increaseCapacity() {
              int increasedSize = element.length * 2;
              Arrays.copyOf(element, increasedSize);
        }

        public int size() {
             return size;
        }
}
 

The main program :--

package com.pr;

public class MainClass {
      public static void main(String[] args) {
            CustomArrayList list = new CustomArrayList();
            list.add("AB");
            list.add("BC");
            System.out.println(list.size());
            System.out.println(list.contains("AB")); 
      }
}
  

  Output : - 2
                  true


Related Post :
Collection Related Interview Questions and Answers in Java(List,Map & Set) 

Friday, 25 August 2017

Spring Bean Scopes: Singleton, Prototype, Request, Session, and Application

        The core of the Spring Framework is the BeanFactory, which is responsible for creating and managing beans within the Spring container. A bean's scope defines the lifecycle of the bean and determines how many instances of the bean are created and managed by the container.

Spring provides five built-in bean scopes. Two of them are available in all Spring applications, while the remaining three are available only in web-aware ApplicationContext implementations. 

The five bean scopes are singleton, prototype, request, session, and application (previously referred to as global session in older versions of Spring).


Spring Bean Scopes
Spring Bean Scopes

  • singleton

With the singleton bean scope, the Spring IoC container creates only one instance of the bean per container, regardless of how many times it is requested. This is the default bean scope in Spring. The Spring container manages and maintains this single instance throughout the application's lifecycle.

Example: EmployeeService.java
package com.adnblog.employee;

public class EmployeeService { 
 
     String message;

     public String getMessage() {
           return message;
     }

     public void setMessage(String message) {
          this.message = message;
     }
}  

Spring bean configuration file : spring-employee.xml (if scope is not declared, default it should be singleton)

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

       <bean id="employeeService"
            class="com.adnblog.employee.EmployeeService" />

</beans>

Spring code - Main Program
 
package com.adnblog;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.adnblog.employee.EmployeeService;

public class MainClass { 
 
       public static void main( String[] args ) { 
 
              ApplicationContext context =
                               new ClassPathXmlApplicationContext(new String[] {"spring-employee.xml"});

              EmployeeService empService = (EmployeeService)context.getBean("employeeService");
              empService.setMessage("empService Message");
              System.out.println("Message : " + empService.getMessage());

              //trying to create second instance
             EmployeeService empService1 = (EmployeeService)context.getBean("employeeService");
             System.out.println("Message : " + empService1.getMessage());
      }
}

Output Message : empService Message
                Message : empService Message


  • prototype

     With the prototype bean scope, the Spring IoC container creates a new instance of the bean each time it is requested. Unlike the singleton scope, a new object is created for every request.

To use the prototype scope, set the bean's scope to prototype in the bean configuration, as shown below:


<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

       <bean id="employeeService"
            class="com.adnblog.employee.EmployeeService"  scope="prototype"/>

</beans>

Run the main program, you will get output  

Output : Message : empService Message

               Message : null



  • request

       With the request bean scope, a new bean instance is created for each HTTP request made by the client. Once the request is completed, the bean goes out of scope and becomes eligible for garbage collection.

This scope is available only in a web-aware ApplicationContext, such as WebApplicationContext.

  • session

    The session bean scope is similar to the request scope, but it creates one bean instance per user session. The same bean instance is shared throughout the user's session. Once the session ends, the bean goes out of scope and becomes eligible for garbage collection.

This scope is available only in a web-aware ApplicationContext, such as WebApplicationContext.


  •  global-session

      The global session scope is specific to Portlet-based applications. In a Portlet container, an application consists of multiple portlets. Each portlet has its own session, but if you want to share a bean instance across all portlets within the same application, you can use the global session scope.

In Servlet-based applications, the global session scope has no special behavior and functions the same as the session scope. It is worth noting that the global session scope is primarily intended for Portlet environments and is rarely used in modern Spring Boot applications.


Saturday, 19 August 2017

Producer Consumer Problem - Solution using BlockingQueue in Java

           In previous post, discussed the Producer Consumer problem-solution using wait() and notify() methods. In this post, we will learn how to solve the Producer Consumer problem using BlockingQueue. 
   
          BlockingQueue is a queue(added in java.util.concurrent package) which is thread safe to insert or retrieve elements from it. And also it provides a mechanism which blocks request for inserting new elements when the queue is full and also blocks request for removing elements when the queue is empty. The classes that implementing BlockingQueue are ArrayBlockingQueue, DelayQueue, LinkedBlockingQueue and PriorityBlockingQueue and so on.

Program to Solve the Producer-Consumer Problem using BlockingQueue :--


package com.pr;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class ProducerConsumer {
     public static void main (String[] args) {
    
          BlockingQueue<Integer> sharedQueue = new LinkedBlockingQueue<Integer>();
          Producer producer = new Producer(sharedQueue);
          Consumer consumer = new Consumer(sharedQueue);
          Thread p = new Thread(producer, "Producer Thread");
          Thread c = new Thread(consumer, "Consumer Thread");
          p.start();
          c.start();
      }
}

class Producer implements Runnable {

      BlockingQueue<Integer> sharedQueue = new LinkedBlockingQueue<Integer>();
 
      public Producer(BlockingQueue<Integer> sharedQueue) {
            this.sharedQueue = sharedQueue;
      }

      public void run() {
            for (int i = 1; i<=10; i++) {
                try {
                      System.out.println("Produced - "+i);
                      sharedQueue.put(i);
                      Thread.sleep(1000);
                } catch(InterruptedException e) {
                      e.printStackTrace();
                }
            }   
       }
}

class Consumer implements Runnable {

       BlockingQueue<Integer> sharedQueue = new LinkedBlockingQueue<Integer>();

       public Consumer(BlockingQueue<Integer> sharedQueue) {
           this.sharedQueue = sharedQueue;
       }

       @Override
       public void run() {
             while (true) {
                 try {
                      System.out.println("Consumed - "+sharedQueue.take());
                 } catch(InterruptedException e) {
                      e.printStackTrace();
                 }
             }
       } 
}
 
OUTPUT : -  
Produced - 1  
Consumed - 1  
Produced - 2  
Consumed - 2  
Produced - 3  
Consumed - 3  
Produced - 4  
Consumed - 4  
Produced - 5  
Consumed - 5  
Produced - 6  
Consumed - 6  
Produced - 7  
Consumed - 7  
Produced - 8  
Consumed - 8  
Produced - 9  
Consumed - 9  
Produced - 10 
Consumed - 10  
 


Related Posts :
Producer Consumer Problem - Solution using wait and notify In Java
Thread(or Multithread) interview questions & answers

Thursday, 10 August 2017

Producer Consumer Problem - Solution using wait and notify In Java

        This is very important question for the experienced interview perspective. This question will ask mostly 4+ years of experienced peoples. In this problem, again two approaches first one using wait and notify another one using BlockingQueue . In this post, we can discuss or solution using wait and notify.
        Before going through solution,  first need to understand the synchronized block and methods. In this producer and consumer problem solution, we are using synchronization concept.

Below example,
       --->  Producer will produce total of 10 products and can not produce more than 1 item at a time until products are being consumed by the consumer
In code, when sharedQueue size is 1, wait for producer till consumer consume the product.

     ---> Consumer can consume products only when products are available.
In code, when sharedQueue size is 0, wait for consumer till producer produce the product.

Program to Solve the Producer-Consumer Problem using wait and notify



    package com.pr;  
  import java.util.ArrayList;  
  import java.util.List;  
  public class ProducerConsumer {  
       public static void main (String[] args) {  
            List<Integer> sharedQueue = new ArrayList<Integer>();  
            Producer producer = new Producer(sharedQueue);  
            Consumer consumer = new Consumer(sharedQueue);  
            Thread p = new Thread(producer, "Producer Thread");  
            Thread c = new Thread(consumer, "Consumer Thread");  
            p.start();  
            c.start();  
       }  
  }
  
  class Producer implements Runnable {  
       List<Integer> sharedQueue = new ArrayList<Integer>();  
       public Producer(List<Integer> sharedQueue) {  
            this.sharedQueue = sharedQueue;  
       }  
       public void run() {  
            for (int i = 1; i<=10; i++) {  
                 try {  
                      produce(i);  
                 } catch(InterruptedException e) {  
                      e.printStackTrace();  
                 }  
            }  
       }  
       private void produce(int i) throws InterruptedException{  
            synchronized (sharedQueue) {  
                 if (sharedQueue.size() == 1) {  
                      System.out.println("Queue is full");  
                      sharedQueue.wait();  
                 }  
            }  
            synchronized (sharedQueue) {  
                 System.out.println("Produced : "+i);  
                 sharedQueue.add(i);  
                 Thread.sleep(1000);  
                 sharedQueue.notify();  
            }  
       }  
  }
  
  class Consumer implements Runnable {  
       List<Integer> sharedQueue = new ArrayList<Integer>();  
       public Consumer(List<Integer> sharedQueue) {  
            this.sharedQueue = sharedQueue;  
       }  
       @Override  
       public void run() {  
            while (true) {  
                 try {  
                      consume();  
                      Thread.sleep(1000);  
                 } catch(InterruptedException e) {  
                      e.printStackTrace();  
                 }  
            }  
       }       
       private void consume() throws InterruptedException{  
            synchronized (sharedQueue) {  
                 while (sharedQueue.size() == 0) {  
                      System.out.println("Queue is empty");  
                      sharedQueue.wait();  
                 }  
            }  
            synchronized (sharedQueue) {  
                 Thread.sleep(1000);  
                 System.out.println("Consumed :" +sharedQueue.remove(0));  
                 sharedQueue.notify();  
            }  
       }  
  }   

Output : - Produced : 1
Queue is full
Consumed : 1
Produced : 2
Queue is full
Consumed : 2
Produced : 3
Queue is full
Consumed : 3
Produced : 4
Queue is full
Consumed : 4
Produced : 5
Consumed : 5
Produced : 6
Queue is full
Consumed : 6
Produced : 7
Consumed : 7
Produced : 8
Consumed : 8
Produced : 9
Queue is full
Consumed : 9
Produced : 10
Consumed : 10
Queue is empty

Another way solving the producer consumer problem is using BlockingQueue.  BlockingQueue can reduce the code complexity no need to write wait and notify.  In next post we can discuss about BlockingQueue.

Related Post:-- 
Producer Consumer Problem - Solution using BlockingQueue in Java