Wednesday, 30 March 2016

DelayQueue in Java

DelayQueue which is an implementation of BlockingQueue interface is added in Java 5 along with other concurrent utilities like CyclicBarrier, Exchanger, ConcurentSkipListMap, CopyOnWriteArraySet etc.

DelayQueue is an unbounded implementation of BlockingQueue, that's where it is different from the other implementation of BlockingQueue like ArrayBlockingQueue (Always bounded) and LinkedBlockingQueue (both bounded and unbounded options). Though it is similar to PriorityBlockingQueue in this behaviour as PriorityBlockingQueue is also unbounded.

DelayQueue stores Delayed elements

DelayQueue is a special implementation of blocking queue as it can only store elements of type Delayed and an element can only be retrieved from DelayQueue when its delay has expired.

Delayed interface which defines the type for the elements in the DelayQueue has one method

  • getDelay(TimeUnit unit) - Returns the remaining delay associated with this object, in the given time unit.

Delayed interface also extends Comparable interface so compareTo(T o) method should also be implemented. This method implementation will decide whether you want to retrieve elements in ascending order of delay or descending.

According to JavaDocs "An implementation of this interface must define a compareTo method that provides an ordering consistent with its getDelay method."

So, just to sum it up; DelayQueue stores elements of type Delayed. When you implement Delayed interface two methods have to be implemented getDelay(TimeUnit unit) and compareTo(T o).

Example Code

Let's create a producer consumer using the DelayQueue. There is also a class DelayClass which implements Delayed interface. DelayQueue will store objects of DelayClass.

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class DelayQDemo {

    public static void main(String[] args) {
        // delay of 2 seconds
        final long delay = 2000;
        BlockingQueue<DelayClass> delayQ = new DelayQueue<DelayClass>();
        
        // Producer thread
        new Thread(){
            @Override
            public void run() {
                for(int i = 0; i < 5; i++){
                    try {
                        // putting elements in delay queue
                        delayQ.put(new DelayClass("item"+i, delay));
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        System.out.println("Error while putting values in the Queue " + e.getMessage());
                    }
                }
            }
        }.start();
        
        // Consumer thread
        new Thread(){
            @Override
            public void run() {
                for(int i = 0; i < 5; i++){
                    try {
                        // retrieving elements from delay queue
                        System.out.println(" Consumer got - " + delayQ.take());
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        System.out.println("Error while retrieving value from the Queue " + e.getMessage());
                    }
                }
            }
        }.start();
    }

}

// Delayed interface implementing class
class DelayClass implements Delayed{
    private String item;
    private long expireTime;
    DelayClass(String item, long delay){
        this.item = item;
        // Expiretime is currenttime+delay, so if delay of 2 sec is required
        // expiration from queue will hppn after
        // currenttime + 2 sec
        this.expireTime = System.currentTimeMillis() + delay;
    }
    
    @Override
    public long getDelay(TimeUnit unit) {
        long diff = expireTime - System.currentTimeMillis();
        return unit.convert(diff, TimeUnit.MILLISECONDS);
    }
    
    @Override
    public int compareTo(Delayed o) {
        if(this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)){
            return -1;
        }
        if(this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)){
            return 1;
        }
        return 0;
            
    }
    
    public String toString(){
        return "item = " + item + " expireTime = " + expireTime;
    } 
}

Output

Consumer got - item = item0 expireTime = 1458998017469
Consumer got - item = item1 expireTime = 1458998017531
Consumer got - item = item2 expireTime = 1458998017594
Consumer got - item = item3 expireTime = 1458998017656
Consumer got - item = item4 expireTime = 1458998017719

Here it can be seen elements are retrieved from the queue only after the delay expires.

Points to remember

  1. DelayQueue stores element of type Delayed.
  2. Element is retrieved from DelayQueue only when its delay has expired.
  3. The head of the queue is thatDelayed element whose delay expired furthest in the past.
  4. If no delay has expired there is no head and poll will return null.
  5. Expiration occurs when an element's getDelay(TimeUnit tu) method returns a value less than or equal to zero.

Source : https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/DelayQueue.html

That's all for this topic DelayQueue in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. SynchronousQueue in Java
  2. BlockingDeque in Java Concurrency
  3. ConcurrentHashMap in Java
  4. ReentrantReadWriteLock in Java
  5. Semaphore in Java concurrency
  6. Java Concurrency interview questions

You may also like -

Monday, 28 March 2016

SynchronousQueue in Java

SynchronousQueue which is an implementation of the BlockingQueue interface was added in Java 5 along with other concurrent utilities like ConcurrentHashMap, ReentrantLock, Phaser, CyclicBarrier etc.

How SynchronousQueue differs from other implementations of BlockingQueue like ArrayBlockingQueue and LinkedBlockingQueue is that synchronous queue does not have any internal capacity, not even a capacity of one. In SynchronousQueue each insert operation must wait for a corresponding remove operation by another thread, and vice versa.

What that means is, if you put an element in SynchronousQueue using put() method it will wait for another thread to receive it, you can't put any other element in the SynchronousQueue as it is blocked. Same way in case there is thread to remove an element (using take() method) but there is no element in the queue it will block and wait for an element in the queue.

Different functionality

Since SynchronousQueue has a very special functionality which differs from other BlockingQueue implementations so methods in SynchronusQueue behave a little differently. Actually calling it a Queue itself is a bit of wrong statement as there is never more than one element present. It's more of a point-to-point handoff.

As stated methods will behave differently so take an example of peek() method, which in other BlockingQueue implementations work as follows-

peek() - Retrieves, but does not remove, the head of this queue, or returns null if this queue is empty.

Since in SynchronousQueue an element is only present when you try to remove it so peek() method in this class will always return null.

Iterator in SynchronousQueue returns an empty iterator in which hasNext always returns false.

For purposes of other Collection methods a SynchronousQueue acts as an empty collection, so methods like

  • contains - Always returns false. A SynchronousQueue has no internal capacity.
  • remove - Always returns false. A SynchronousQueue has no internal capacity.
  • isEmpty() - Always returns true. A SynchronousQueue has no internal capacity.

No nulls

SynchronousQueue does not permit null elements.

Usage of SynchronousQueue

As already stated that calling it a Queue itself is a bit of wrong statement as there is never more than one element present. It's more of a point-to-point handoff. So SynchronousQueue is well suited for handoff designs, in which an object running in one thread must sync up with an object running in another thread in order to hand it some information, event, or task.

Fairness policy

This class supports an optional fairness policy for ordering waiting producer and consumer threads. By default, this ordering is not guaranteed. However, a queue constructed with fairness set to true grants threads access in FIFO order.

Thus SynchronousQueue has two constructors -

  • SynchronousQueue() - Creates a SynchronousQueue with nonfair access policy.
  • SynchronousQueue(boolean fair) - Creates a SynchronousQueue with the specified fairness policy.

Example Code

Let's create a producer consumer using the SynchronousQueue. There is a Producer class which will put elements in the Queue, there is a Consumer class which will retrieve elements from the queue. Also a SharedClass which acts as a bounded buffer.

To see the functionality of SynchronousQueue in practice there are some changes in the code. You can see after every get() in the Consumer class some delay has been induced using sleep() method of the thread. What you can see here is that put will not add more than one element even if the consumer thread is sleeping. It will put one element and block.

Also in producer for loop runs 5 times though in consumer it is only 3 times. So here you can see SynchronousQueue will not add other elements for which there is no thread to retrieve and it will block. So you'll have to forcibly stop this program.

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

public class SyncQDemo {

    public static void main(String[] args) {
        SharedClass buffer = new SharedClass();
        // Starting two threads
        ExecutorService executor = Executors.newFixedThreadPool(2);
        executor.execute(new Producer(buffer));
        executor.execute(new Consumer(buffer));
        executor.shutdown();

    }

}

/**
 * 
 * 
 *
 */
class Producer implements Runnable{
    SharedClass buffer;
    Producer(SharedClass buffer){
        this.buffer = buffer;
    }
    @Override
    public void run() {
        for(int i = 0; i < 5; i++){
            System.out.println("Putting - " + i);
            buffer.put(i);
        }
    }
}

/**
 * 
 * 
 *
 */
class Consumer implements Runnable{
    SharedClass buffer;
    Consumer(SharedClass buffer){
        this.buffer = buffer;
    }
    @Override
    public void run() {
        for(int i = 0; i < 3; i++){
            buffer.get();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }    
}

//Shared class used by threads
class SharedClass{
    int i;
    // SynchronousQueue
    BlockingQueue<Integer> syncQ = new SynchronousQueue<Integer>();
    public void get(){
        // retrieve from synchronousQueue
        try {
            System.out.println("Consumer recd - " + syncQ.take());
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    public void put(int i){
        this.i = i;
        try {
            
            // putting in synchronousQueue
            syncQ.put(i);
            System.out.println("In Queue " + i);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
}

Output

Putting - 0
Consumer recd - 0
In Queue 0
Putting - 1
Consumer recd - 1
In Queue 1
Putting - 2
Consumer recd - 2
In Queue 2
Putting - 3 

Source : https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/SynchronousQueue.html

That's all for this topic SynchronousQueue in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. BlockingQueue in Java Concurrency
  2. BlockingDeque in Java Concurrency
  3. ConcurrentSkipListSet in Java
  4. Exchanger in Java concurrency
  5. ReentrantLock in Java concurrency
  6. Java Concurrency interview questions

You may also like -

Wednesday, 23 March 2016

PriorityBlockingQueue in Java

PriorityBlockingQueue class was added in Java 5 and it implements the BlockingQueue interface. PriorityBlockingQueue class uses the same ordering rules as the PriorityQueue class. In fact PriorityBlockingQueue can be termed as the thread-safe alternative of the PriorityQueue as it has blocking retrieval operations.

While this queue is logically unbounded, attempted additions may fail due to resource exhaustion (causing OutOfMemoryError). That's where it differs from the other implementations of BlockingQueue like ArrayBlockingQueue (Always bounded) and LinkedBlockingQueue (both bounded and unbounded options).

As Example put(E e) method in ArrayBlockingQueue or LinkedBlockingQueue will wait if necessary for space to become available.

Whereas put(E e) method in PriorityBlockingQueue will never block as it is unbounded.

Elements are sorted

The elements of the PriorityBlockingQueue are ordered according to their natural ordering, or by a Comparator provided at queue construction time, depending on which constructor is used.

PriorityBlockingQueue Contructors

  • PriorityBlockingQueue() - Creates a PriorityBlockingQueue with the default initial capacity (11) that orders its elements according to their natural ordering.

  • PriorityBlockingQueue(Collection<? extends E> c) - Creates a PriorityBlockingQueue containing the elements in the specified collection.

  • PriorityBlockingQueue(int initialCapacity) - Creates a PriorityBlockingQueue with the specified initial capacity that orders its elements according to their natural ordering.

  • PriorityBlockingQueue(int initialCapacity, Comparator<? super E> comparator) - Creates a PriorityBlockingQueue with the specified initial capacity that orders its elements according to the specified comparator.

Nulls are not allowed

PriorityBlockingQueue class does not permit null elements.

Non-comparable objects not allowed

A priority queue relying on natural ordering also does not permit insertion of non-comparable objects (doing so results in ClassCastException).

Iterator

Note that though elements are stored using natural ordering, Iterator provided in method iterator() is not guaranteed to traverse the elements of the PriorityBlockingQueue in any particular order. If you need ordered traversal, consider using Arrays.sort(pq.toArray()).

Example Code

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;

public class PriorityQDemo {

    public static void main(String[] args) {
        String[] cityNames = {"Delhi", "Mumbai", "Chennai", "Bangalore", 
                "Hyderabad", "Lucknow"};
        // initializing PriortiyBlockingQueue
        BlockingQueue<String> priortyBQ = new PriorityBlockingQueue<String>();
        
        // Producer thread
        new Thread(){
            @Override
            public void run() {
                for(int i = 0; i < cityNames.length; i++){
                    try {
                        priortyBQ.put(cityNames[i]);
                    } catch (InterruptedException e) {
                        System.out.println("Error while putting values in the Queue " 
+ e.getMessage());
                    }
                }
            }
        }.start();
        
        // Consumer thread
        new Thread(){
            @Override
            public void run() {
                for(int i = 0; i < cityNames.length; i++){
                    try {
                        System.out.println(" Consumer got - " + priortyBQ.take());
                    } catch (InterruptedException e) {
                        System.out.println("Error while retrieving value from the Queue " + e.getMessage());
                    }
                }
            }
        }.start();
    }
}

Output

Consumer got - Bangalore
Consumer got - Chennai
Consumer got - Delhi
Consumer got - Hyderabad
Consumer got - Lucknow
Consumer got - Mumbai

It can be seen here that the city names are ordered.

You can also use a comparator, if you want different ordering than the natural ordering. Here, if you want the cities in reverse order you can use the constructor that takes comparator as parameter.

Example Code

import java.util.Comparator;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;

public class PriorityQDemo {

    public static void main(String[] args) {
        String[] cityNames = {"Delhi", "Mumbai", "Chennai", "Bangalore", 
                "Hyderabad", "Lucknow"};
        // initializing PriortiyBlockingQueue
        BlockingQueue<String> priortyBQ = new PriorityBlockingQueue<String>(10, new CityComparator());
        
        // Producer thread
        new Thread(){
            @Override
            public void run() {
                for(int i = 0; i < cityNames.length; i++){
                    try {
                        priortyBQ.put(cityNames[i]);
                    } catch (InterruptedException e) {
                        System.out.println("Error while putting values in the Queue " + e.getMessage());
                    }
                }
            }
        }.start();
        
        // Consumer thread
        new Thread(){
            @Override
            public void run() {
                for(int i = 0; i < cityNames.length; i++){
                    try {
                        System.out.println(" Consumer got - " + priortyBQ.take());
                    } catch (InterruptedException e) {
                        System.out.println("Error while retrieving value from the Queue " + e.getMessage());
                    }
                }
            }
        }.start();
    }
}

// Comparator class
class CityComparator implements Comparator<String>{
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }    
}

Output

Consumer got - Mumbai
Consumer got - Lucknow
Consumer got - Hyderabad
Consumer got - Delhi
Consumer got - Chennai
Consumer got - Bangalore 

That's all for this topic PriorityBlockingQueue in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. BlockingQueue in Java Concurrency
  2. ArrayBlockingQueue in Java Concurrency
  3. LinkedBlockingQueue in Java Concurrency
  4. BlockingDeque in Java Concurrency
  5. ConcurrentSkipListSet in Java
  6. Java Concurrency interview questions

You may also like -

Tuesday, 22 March 2016

BlockingDeque in Java

BlockingDeque interface (added in Java 6) is a Deque that provides additional support for blocking operations. Here blocking the opearations mean that the operation will wait for the deque to become non-empty (means deque has atleast one element) when retrieving an element, and wait for space to become available in the deque when storing an element.

What is Deque

Deque is also an interface which was added in Java 6. Deque is short for "double ended queue". As the name suggests Deque supports element insertion and removal at both ends.

BlockingDeque methods

As already mentioned BlockingDeque provide support for the blocking operation, but blocking methods come in four forms, categorized in the way these methods will handle operations that cannot be satisfied immediately, but may be satisfied at some point in the future:

  • Throw exception - Methods falling in this category will throw exception if blocked.
  • Return special value - This type of methods will return some value if need to wait, like false.
  • Blocks - This type of methods will wait if necessary for space to become available.
  • Times out - This type of methods will block for only a given maximum time limit before giving up.

These methods are summarized in the following table:

First Element (Head)
Throws exception Special value Blocks Times out
Insert addFirst(e) offerFirst(e) putFirst(e) offerFirst(e, time, unit)
Remove removeFirst() pollFirst() takeFirst() pollFirst(time, unit)
Examine getFirst() peekFirst() not applicable not applicable
Last Element (Tail)
Throws exception Special value Blocks Times out
Insert addLast(e) offerLast(e) putLast(e) offerLast(e, time, unit)
Remove removeLast() pollLast() takeLast() pollLast(time, unit)
Examine getLast() peekLast() not applicable not applicable

No null elements

Like any BlockingQueue, a BlockingDeque is thread safe, does not permit null elements, and may (or may not) be capacity-constrained.

BlockingDeque implementation

LinkedBlockingDeque class in Java is the implementation of the BlockingDeque interface.

Example Code

Let's create a produce consumer bounded buffer using LinkedBlockingDeque which is an implmentation of BlockingDeque.

Values will be inserted in the LinkedBlockingDeque using put() method, which will block if the space is full.

Values will be retrieved from the LinkedBlockingDeque using take() method, which retrieves and removes the head of this queue, waiting if necessary until an element becomes available.

Here in the Produce class some delay is induced using sleep() method. You can see that in Consumer class, where it is taking elements out of the deque, no exception will be thrown but it will block. If you are using eclipse you can see that delay in the console when it is printing. Later we'll see the same example using deque which is not thread safe there it will throw an exception.

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

public class LinkedBlockingDQDemo {
    public static void main(String[] args) {
        SharedClass buffer = new SharedClass();
        // Starting two threads
        ExecutorService executor = Executors.newFixedThreadPool(2);
        executor.execute(new Producer(buffer));
        executor.execute(new Consumer(buffer));
        executor.shutdown();

    }
}


/**
 * 
 * 
 *
 */
class Producer implements Runnable{
    SharedClass buffer;
    Producer(SharedClass buffer){
        this.buffer = buffer;
    }
    @Override
    public void run() {
        for(int i = 0; i < 10; i++){
            buffer.put(i);
            if(i == 4){
                try {
                    // introducing some delay using sleep
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}

/**
 * 
 * 
 *
 */
class Consumer implements Runnable{
    SharedClass buffer;
    Consumer(SharedClass buffer){
        this.buffer = buffer;
    }
    @Override
    public void run() {
        for(int i = 0; i < 10; i++){
            buffer.get();;
        }
    }    
}

//Shared class used by threads
class SharedClass{
    int i;
    // Bounded LinkedBlockingDeque of size 10
    BlockingDeque<Integer> linkedBlockingDeque = new LinkedBlockingDeque<Integer>(10);
    
    public void get(){
       try {
            // take method to get from blockingdeque
           System.out.println("Consumer recd - " + linkedBlockingDeque.take());
       } catch (InterruptedException e) {
            // TODO Auto-generated catch block
           e.printStackTrace();
       }
    }
    
    public void put(int i){
       this.i = i;
       try {
            // putting in blocking deque
            linkedBlockingDeque.put(i);
            System.out.println("Putting - " + i);
       }
       catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
       } 
    }
}

Output

Putting - 0
Putting - 1
Putting - 2
Putting - 3
Putting - 4
Consumer recd - 0
Consumer recd - 1
Consumer recd - 2
Consumer recd - 3
Consumer recd - 4
Putting - 5
Consumer recd - 5
Putting - 6
Consumer recd - 6
Putting - 7
Consumer recd - 7
Putting - 8
Consumer recd - 8
Putting - 9
Consumer recd - 9

Now let's write the same code as above using the Deque which is not thread safe. Here one change is instead of LinkedBlockingDeque, ArrayDeque is used which is implementation of Deque and also some delay is induced in consumer class too just to make sure that producer will start first. Then producer sleeps for 1000 MS, that is when exception is thrown.

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

public class DQDemo {
    public static void main(String[] args) {
        SharedClass buffer = new SharedClass();
        // Starting two threads
        ExecutorService executor = Executors.newFixedThreadPool(2);
        executor.execute(new Producer(buffer));
        executor.execute(new Consumer(buffer));
        executor.shutdown();

    }
}

/**
 * 
 * 
 *
 */
class Producer implements Runnable{
    SharedClass buffer;
    Producer(SharedClass buffer){
        this.buffer = buffer;
    }
    @Override
    public void run() {
        for(int i = 0; i < 10; i++){
            buffer.put(i);
            if(i == 4){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}

/**
 * 
 * 
 *
 */
class Consumer implements Runnable{
    SharedClass buffer;
    Consumer(SharedClass buffer){
        this.buffer = buffer;
    }
    @Override
    public void run() {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        for(int i = 0; i < 10; i++){
            buffer.get();;
        }
    }    
}

//Shared class used by threads
class SharedClass{
    int i;
    // Bouded ArrayDeque of size 10
    Deque<Integer> arrayDq = new ArrayDeque<Integer>(10);
    public void get(){
        // retrieve from deque
        System.out.println("Consumer recd - " + arrayDq.pop());
    }
    
    public void put(int i){
        this.i = i;
        arrayDq.push(i);
        System.out.println("Putting - " + i);
    }
}

Output

Putting - 0
Putting - 1
Putting - 2
Putting - 3
Putting - 4
Consumer recd - 4
Consumer recd - 3
Consumer recd - 2
Consumer recd - 1
Consumer recd - 0
Exception in thread "pool-1-thread-2" java.util.NoSuchElementException
 at java.util.ArrayDeque.removeFirst(Unknown Source)
 at java.util.ArrayDeque.pop(Unknown Source)
 at org.netjs.prgrm.SharedClass.get(DQDemo.java:77)
 at org.netjs.prgrm.Consumer.run(DQDemo.java:65)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
 at java.lang.Thread.run(Unknown Source)
Putting - 5
Putting - 6
Putting - 7
Putting - 8
Putting - 9

Source : https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/BlockingDeque.html

That's all for this topic BlockingDeque in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. LinkedBlockingDeque
  2. ArrayBlockingQueue in Java Concurrency
  3. LinkedBlockingQueue in Java Concurrency
  4. CopyOnWriteArrayList in Java
  5. Java Concurrency interview questions

You may also like -

Monday, 14 March 2016

effectively final in Java 8

In Java 8 with the addition of lambda expressions, a new concept effectively final variable has been added, which closely relates to lambda expressions.

Prior to Java 8, inner classes had an important restriction that inner classes could only use variable from enclosing scope if it's final.

Example Code

Let's see an example code, where we have an interface IFunc, with one mthod display(). That interface is implemented as an anonymous class in Test class. In the implementation of display() method it tries to access the varibale i from the enclosing scope which is not declared as final variable. Note that this code is compiled and executed using Java 6.

interface IFunc{
  void display();
}

public class Test {

 /**
  * @param args
  */
 public static void main(String[] args) {
  int i =7;
  // Anonymous inner class
  new IFunc() {
   @Override
   public void display() {
    System.out.println("Value is " + i);
    
   }
  };
 }
}

Output

There will be a compile time error -

Cannot refer to a non-final variable i inside an inner class defined in a different method

Effectively final in Java 8

With Java 8 this restriction of declaring the variable in the enclosing scope as final has been eased a bit. If you are accessing a variable from the enclosing scope in an inner class (or lambda expression for that matter) you are not forced by compiler to declare that variable as final (though declaring the variable as final is still ok).

Note here that you still can't change the value of that variable. Doing so will result in "local variable defined in an enclosing scope must be final or effectively final" error.

Let's write the same code as above using Lambda expression in Java 8 now -

@FunctionalInterface
interface  IFunc{
    void display();
}

public class InnerDemo {
    
    public static void main(String[] args) {
        int i = 7;
        // lambda expression that implements the display method 
        // of the IFunc functional interface 
        IFunc ifunc = ()-> System.out.println("Value of i is " + i);
        // Calling the display method
        ifunc.display();
    }   
}

Output

Value of i is 7

It can be seen if you are not changing the value of local variable i, it can be used with lambda expression and there is no need to declare i as final.

With inner class also you won't get error now. If you'll compile the same code (inner class implementation) which was not running in Java 6, it will compile with Java 8.

What will give error

As already stated you still can't change the value of the variable used from the enclosed scope, trying to do that will result in error.

Example Code

If you try to change the value of i with in the lambda expression you'll get the error "Local variable i defined in an enclosing scope must be final or effectively final".

effectively final

Here it can be seen variable i from the enclosing scope is changed with in the lambda expression by trying to print i++. Thus compile time error is thrown that "Local variable i defined in an enclosing scope must be final or effectively final"

That's all for this topic effectively final in Java 8. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. final in Java
  2. interface static methods in Java 8
  3. interface default methods in Java 8
  4. Optional class in Java 8
  5. Functional interfaces & lambda expression
  6. How to resolve Local variable defined in an enclosing scope must be final or effectively final error

You may also like -

>>>Go to Java advance topics page

LinkedBlockingQueue in Java

LinkedBlockingQueue which is an implementation of BlockingQueue interface is added in Java 5 along with other concurrent utilities like CyclicBarrier, Phaser, ConcurentHashMap, CopyOnWriteArraySet etc.

LinkedBlockingQueue internally uses linked nodes to store elements. It is optionally bounded and that's where it differs from another implementation of BlockingQueue, ArrayBlockingQueue which is bounded, another difference between the two is how elements are stored internally ArrayBlockingQueue uses array internally whereas LinkedBlockingQueue uses linked nodes.

Since it is optionally bounded so it has both type of constructors

  • one where initial capacity can be passed thus making it bounded.
  • Or
  • without any capacity thus making it unbounded. Note that in case no initial capacity is defined capacity of LinkedBlockingQueue is Integer.MAX_VALUE.

Constructors

  • LinkedBlockingQueue(int capacity) - Creates a LinkedBlockingQueue with the given (fixed) capacity.
  • LinkedBlockingQueue() - Creates a LinkedBlockingQueue with a capacity of Integer.MAX_VALUE.

How elements are stored

LinkedBlockingQueue orders elements in first-in-first-out (FIFO) order. The head of the queue is that element that has been on the queue the longest time. The tail of the queue is that element that has been on the queue the shortest time.

New elements are inserted at the tail of the queue, and the queue retrieval operations obtain elements at the head of the queue.

LinkedBlockingQueue methods

Since LinkedBlockingQueue also implements Iterable, Collection and Queue interfaces apart from BlockingQueue interface so This class and its iterator implement all of the optional methods of the Collection and Iterator interfaces.

For the same type of functionality like adding an element or removing an element LinkedBlockingQueue provides different methods which will throw exception, block or timeout based on the method used. Refer BlockingQueue to see the table of methods.

Example Code

Let's create a producer consumer using the LinkedBlockingQueue. Initial capacity of the LinkedBlockingQueue will be kept one so that producer and consumer both get a chance alternatively.

Values will be inserted in the LinkedBlockingQueue using put() method, which will block if the space is full. Values will be retrieved from the LinkedBlockingQueue using take() method, which retrieves and removes the head of this queue, waiting if necessary until an element becomes available.

public class LinkedBQDemo {
    public static void main(String[] args) {
        Buffer buffer = new Buffer();
        // Starting two threads
        ExecutorService executor = Executors.newFixedThreadPool(2);
        executor.execute(new ProdTask(buffer));
        executor.execute(new ConTask(buffer));
        executor.shutdown();
    }

}

/**
 * 
 * Producer class
 *
 */
class LinkProdTask implements Runnable{
    Buffer buffer;
    LinkProdTask(Buffer buffer){
        this.buffer = buffer;
    }
    @Override
    public void run() {
        for(int i = 0; i < 5; i++){
            buffer.put(i);
        }
    }
}

/**
 * 
 * Consumer Class
 *
 */
class LinkConTask implements Runnable{
    Buffer buffer;
    LinkConTask(Buffer buffer){
        this.buffer = buffer;
    }
    @Override
    public void run() {
        for(int i = 0; i < 5; i++){
            buffer.get();;
        }
    }    
}

//Shared class used by threads
class LinkBuffer{
    int i;
    // Bounded LinkedBlockingQueue of size 1
    BlockingQueue<Integer> linkedBlockingQ = new LinkedBlockingQueue<Integer>(1);
    public void get(){
        try {
            // take method to get from blockingqueue
            int i = linkedBlockingQ.take();
            System.out.println("Consumer recd - " + i);
        } catch (InterruptedException e) {
            System.out.println("Error " + e.getMessage());
        }
    }
    
    public void put(int i){
        this.i = i;
        try {
            // putting in blocking queue
            linkedBlockingQ.put(i);
            System.out.println("Putting - " + i);
        } catch (InterruptedException e) {
            System.out.println("Error " + e.getMessage());
        }
        
    }
}

Output

Putting - 0
Consumer recd - 0
Putting - 1
Consumer recd - 1
Putting - 2
Consumer recd - 2
Putting - 3
Consumer recd - 3
Putting - 4
Consumer recd - 4

Here it can be seen how put and take methods are working simultaneously and the respective method blocks, in the case of put() it blocks if space is full (size is 1 only) and take() method blocks unless there is any element to retrieve.

Compare this implementation with producer-counsumer implementation using wait, notify, notifyall where you need to do a lot of work yourself for inter-thread communication or with producer-counsumer implementation using semaphore and you will see how much simplified it is using a BlockingQueue implementation.

That's all for this topic LinkedBlockingQueue in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. BlockingQueue in Java Concurrency
  2. ArrayBlockingQueue in Java Concurrency
  3. ConcurrentSkipListSet in Java
  4. Exchanger in Java concurrency
  5. ReentrantLock in Java concurrency
  6. Java Concurrency interview questions

You may also like -

Wednesday, 9 March 2016

ConcurrentSkipListSet in Java

ConcurrentSkipListSet is a scalable concurrent set which uses ConcurrentSkipListMap internally. Though concurrent collections like ConcurrentHashMap and CopyOnWriteArraySet were added in Java 1.5, ConcurrentSkipListSet and the similar map implementation ConcurrentSkipListMap were added in Java 1.6.

ConcurrentSkipListSet

Since ConcurrentSkipListSet implements NavigableSet, it is a sorted set just like TreeSet with added feature of being concurrent. Which essentially means it is a sorted data structure which can be used by multiple threads where as TreeSet is not thread safe.

The elements of the set are kept sorted according to their natural ordering, or by a Comparator provided at set creation time, depending on which constructor is used.

ConcurrentSkipListSet provides a constructor that takes a comparator as a parameter.

  • ConcurrentSkipListSet(Comparator<? super E> comparator) - Constructs a new, empty set that orders its elements according to the specified comparator.

ConcurrentSkipListSet implementation provides expected average log(n) time cost for the contains, add, and remove operations and their variants. Insertion, removal, and access operations safely execute concurrently by multiple threads.

No Nulls

ConcurrentSkipListSet does not permit the use of null elements, because null arguments and return values cannot be reliably distinguished from the absence of elements.

Example Code

Let's see an example where we add some values in a ConcurrentSkipListSet and in the output it can be seen that the elements are sorted. In this example elements are of type String and for String natural ordering is ascending alphabetical order. So when you iterate the set you'll see it is in sorted same way.

Note that ConcurrentSkipListSet like any other set implementation i.e. HashSet can only store unique elements. Also, as mentioned internally it uses ConcurrentSkipListMap so when you call add method of ConcurrentSkipListSet it will in turn call putIfAbsent() method of the concurrentMap, that way element is stored only if it is not there already.

import java.util.Iterator;
import java.util.NavigableSet;
import java.util.concurrent.ConcurrentSkipListSet;

public class CSSDemo {

    public static void main(String[] args) {
        NavigableSet<String> citySet = new ConcurrentSkipListSet<String>();
        citySet.add("New Delhi");
        citySet.add("Mumbai");
        citySet.add("Chennai");
        citySet.add("Hyderabad");
        
        System.out.println("---- Traversing the set-----");
        Iterator<String> itr = citySet.iterator();
        while(itr.hasNext()){
            System.out.println("Value -  " + itr.next());
        }
    }
}

Output

---- Traversing the set-----
Value -  Chennai
Value -  Hyderabad
Value -  Mumbai
Value -  New Delhi

Navigable methods

As already mentioned ConcurrentSkipListSet implements NavigableSet interface so it has many navigation methods returning the closest matches for given search targets. Let's see some of them in example code.

  • higher(E e) - Returns the least element in this set strictly greater than the given element, or null if there is no such element.
  • lower(E e) - Returns the greatest element in this set strictly less than the given element, or null if there is no such element.
  • tailSet(E fromElement) - Returns a view of the portion of this set whose elements are greater than or equal to fromElement.
import java.util.Iterator;
import java.util.NavigableSet;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;

public class CSSDemo {
    public static void main(String[] args) {
        NavigableSet<String> citySet = new ConcurrentSkipListSet<String>();
        citySet.add("New Delhi");
        citySet.add("Mumbai");
        citySet.add("Chennai");
        citySet.add("Hyderabad");
        
        System.out.println("---- Traversing the set-----");
        Iterator<String> itr = citySet.iterator();
        while(itr.hasNext()){
            System.out.println("Value -  " + itr.next());
        }
        
        System.out.println("Higher - " + citySet.higher("C"));
        
        System.out.println("Lower - " + citySet.lower("Mumbai"));
        
        System.out.println("---- Tail Set -----");
        
        Set<String> set = citySet.tailSet("Hyderabad");
        
        itr = set.iterator();
        while(itr.hasNext()){
            System.out.println("Value -  " + itr.next());
        }
    }
}

Output

---- Traversing the set-----
Value -  Chennai
Value -  Hyderabad
Value -  Mumbai
Value -  New Delhi
Higher - Chennai
Lower - Hyderabad
---- Tail Set -----
Value -  Hyderabad
Value -  Mumbai
Value -  New Delhi

Here higher as the description says is returning the least element in this set strictly greater than the given element. Since given element is "C" so returned value is "Chennai". Note that passed element doesn't have to be the one already present in set as here "C" is passed which is not an element of the Set.

lower as the description says is returning the greatest element in this set strictly less than the given element. Passed element is "Mumbai" so that returned element is "Hyderabad".

That's all for this topic ConcurrentSkipListSet in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. ConcurrentSkipListMap in Java
  2. ConcurrentHashMap in Java
  3. CopyOnWriteArraySet in Java
  4. ArrayBlockingQueue in Java Concurrency
  5. CountDownLatch in Java concurrency
  6. Java Concurrency interview questions

You may also like -

Monday, 7 March 2016

ConcurrentSkipListMap in Java

ConcurrentSkipListMap is a scalable concurrent map which implements ConcurrentNavigableMap interface. Though concurrent collections like ConcurrentHashMap and CopyOnWriteArrayList were added in Java 1.5, ConcurrentSkipListMap and the similar set implementation ConcurrentSkipListSet were added in Java 1.6.

ConcurrentNavigableMap interface

ConcurrentNavigableMap interface is a ConcurrentMap supporting NavigableMap operations, and recursively so for its navigable sub-maps. It was added in Java 1.6.

Where NavigableMap is a SortedMap extended with navigation methods returning the closest matches for given search targets. Methods lowerEntry, floorEntry, ceilingEntry, and higherEntry return Map.Entry objects associated with keys respectively less than, less than or equal, greater than or equal, and greater than a given key, returning null if there is no such key. Similarly, methods lowerKey, floorKey, ceilingKey, and higherKey return only the associated keys. All of these methods are designed for locating, not traversing entries.

ConcurrentSkipListMap

Since ConcurrentSkipListMap implements ConcurrentNavigableMap, it is a sorted map just like TreeMap (Which also implements NavigableMap interface).

ConcurrentSkipListMap is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.

ConcurrentSkipListMap provides four constructors, out of those 2 relevant ones are -

  • ConcurrentSkipListMap() - Constructs a new, empty map, sorted according to the natural ordering of the keys.
  • ConcurrentSkipListMap(Comparator<? super K> comparator) - Constructs a new, empty map, sorted according to the specified comparator.

This class implements a concurrent variant of SkipLists providing expected average log(n) time cost for the containsKey, get, put and remove operations and their variants. Insertion, removal, update, and access operations safely execute concurrently by multiple threads.

All Map.Entry pairs returned by methods in this class and its views represent snapshots of mappings at the time they were produced.

No nulls

Note that ConcurrentSkipListMap class does not permit the use of null keys or values because some null return values cannot be reliably distinguished from the absence of elements.

Example Code

Let's see an example where we add some values in a ConcurrentSkipListMap and in the output it can be seen that it is sorted based on the natural ordering of its keys. In this example keys are Strings and for String natural ordering is ascending alphabetical order. So when you loop the map you'll see it is sorted based on the keys.

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;

public class CSMDemo {

    public static void main(String[] args) {
        ConcurrentNavigableMap<String, String> cityMap = new ConcurrentSkipListMap<String, String>();
        cityMap.put("ND", "New Delhi");
        cityMap.put("MU", "Mumbai");
        cityMap.put("CH", "Chennai");
        cityMap.put("HD", "Hyderabad");
        Set<Map.Entry<String, String>> citySet = cityMap.entrySet();
        citySet.forEach((m)->System.out.println("key " + m.getKey() 
                 + " value " + m.getValue()));

    }
}

Output

key CH value Chennai
key HD value Hyderabad
key MU value Mumbai
key ND value New Delhi

Here it can be seen that ConcurrentNavigableMap is sorted on the keys.

Navigational methods

As already mentioned ConcurrentSkipListMap implements ConcurrentNavigableMap interface so it has many navigation methods returning the closest matches for given search targets. Let's see some of them in example code.

  • descendingKeySet() - Returns a reverse order NavigableSet view of the keys contained in this map.
  • floorEntry(K key) - Returns a key-value mapping associated with the greatest key less than or equal to the given key, or null if there is no such key.
  • headMap(K toKey) - Returns a view of the portion of this map whose keys are strictly less than toKey.
  • higherKey(K key) - Returns the least key strictly greater than the given key, or null if there is no such key.
import java.util.Iterator;
import java.util.Map;
import java.util.NavigableSet;
import java.util.Set;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;

public class CSMDemo {

    public static void main(String[] args) {
        ConcurrentNavigableMap<String, String> cityMap = new ConcurrentSkipListMap<String, String>();
        cityMap.put("ND", "New Delhi");
        cityMap.put("MU", "Mumbai");
        cityMap.put("CH", "Chennai");
        cityMap.put("HD", "Hyderabad");
        System.out.println("---- Traversing the map-----");
        Set<Map.Entry<String, String>> citySet = cityMap.entrySet();
        // using for-each loop in Java 8
        citySet.forEach((m)->System.out.println("key " + m.getKey() + 
                " value " + m.getValue()));
        
        NavigableSet<String> reverseKeys = cityMap.descendingKeySet();
        // using iterator
        Iterator<String> itr = reverseKeys.iterator();
        System.out.println("---- Map keys in reverse order-----");
        while(itr.hasNext()){
            System.out.println("Key " + itr.next());
        }
        
        System.out.println("---- Floor entry-----");
        
        Map.Entry<String, String> tempMap = cityMap.floorEntry("II");
        System.out.println(tempMap);
        
        System.out.println("---- Head Map-----");
        ConcurrentNavigableMap<String, String> map = cityMap.headMap("MU");
        Set<Map.Entry<String, String>> set = map.entrySet();
        // using for-each loop in Java 8
        set.forEach((m)->System.out.println("key " + m.getKey() + 
                    " value " + m.getValue()));
        
        System.out.println("---- Higher entry-----");
        
        tempMap = cityMap.higherEntry("II");
        System.out.println(tempMap);
    }
}

Output

---- Traversing the map-----
key CH value Chennai
key HD value Hyderabad
key MU value Mumbai
key ND value New Delhi
---- Map keys in reverse order-----
Key ND
Key MU
Key HD
Key CH
---- Floor entry-----
HD=Hyderabad
---- Head Map-----
key CH value Chennai
key HD value Hyderabad
---- Higher entry-----
MU=Mumbai

DescendingKeySet returns the keys in reverse order.

floorEntry() method returns the greatest key less than or equal to the given key. Here key is provided as "II" if you see greatest key less than or equal to "II" is "HD". Note here that key provided should not be a key already present in the Map ("II" is not a key present in the Map).

That's all for this topic ConcurrentSkipListMap in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. ConcurrentHashMap in Java
  2. CyclicBarrier in Java concurrency
  3. ArrayBlockingQueue in Java Concurrency
  4. How to Sort elements in different order in TreeSet
  5. Java Concurrency interview questions

You may also like -

Friday, 4 March 2016

Spring bean life cycle

Lifecycle of a bean in a Spring is quite elaborate and provides many callback methods to customize the nature of the bean.

On the basis of functionality, these callback methods provide, you can categorize them into two categories -

  1. Callback methods called at the time of instantiating a bean.
  2. Callback methods called at the time of disposing a bean.

Within the span of instantiating and later disposing a bean, Spring framework provides the following interfaces for implementing life cycle methods.

  1. InitializingBean and DisposableBean interfaces which you can implement and provide implementation for afterPropertiesSet() for the former (InitializingBean) and destroy() for the latter (DisposableBean) to allow the bean to perform certain actions upon initialization and destruction of your beans.
  2. There are other ways to provide the functionality as provided by InitializingBean and DisposableBean interfaces.

    Using @PostConstruct and @PreDestroy annotations. If you don't want to use the JSR-250 annotations consider the use of init-method and destroy-method object definition metadata.

    According to Spring docs it is better to use these annotations or init-method and destroy-method for receiving lifecycle callbacks because using them means your beans are not coupled to Spring specific interfaces.

  3. Other aware interfaces like ApplicationContextAware and BeanNameAware.
bean lifecycle in Spring
Spring bean lifecycle methods

Here note that you have three options for controlling bean lifecycle behavior:

the InitializingBean and DisposableBean callback interfaces; 
custom init() and destroy() methods; and 
the @PostConstruct and @PreDestroy annotations. 

You can combine these mechanisms to control a given bean.

If multiple lifecycle mechanisms are configured for a bean, and each mechanism is configured with a different method name, then each configured method is executed in the order listed below.

For intialization methods

  • Methods annotated with @PostConstruct
  • afterPropertiesSet() as defined by the InitializingBean callback interface
  • A custom configured init() method

Destroy methods are called in the same order:

  • Methods annotated with @PreDestroy
  • destroy() as defined by the DisposableBean callback interface
  • A custom configured destroy() method

InitializingBean and DisposbleBean callback interfaces

InitializingBean interface has a single method afterPropertiesSet() which can be implemented to provide any initialization related code.

DisposbleBean interface has a single method destroy() which can be implemented to provide any cleanup code at the time of the destruction of the bean.

Example code

Let's see an example where we have PayServiceImpl bean which will implement InitializingBean and DisposbleBean interfaces and provide implementation for the afterPropertiesSet() and destroy() methods.

XML Configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
 
 <!-- defining CashPayment bean -->
  <bean id="cashPaymentBean" class="org.netjs.exp.Spring_Example.CashPayment" />
 
  <!-- Defining PayServiceImpl bean and injecting payment bean -->
  <bean id="payServiceBean" class="org.netjs.exp.Spring_Example.PayServiceImpl" >
      <property name="payment" ref="cashPaymentBean" />
  </bean>
</beans>

PayServiceImpl class

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;


public class PayServiceImpl implements IPayService, InitializingBean, DisposableBean {
 
 private IPayment payment;
 
 public PayServiceImpl(){
  
 }
 public PayServiceImpl(IPayment payment){
  this.payment = payment;
 }
 
 public void performPayment() {
  payment.executePayment();
 }

 public void destroy() throws Exception {
  System.out.println("Calling destroy method");
  
 }

 public void afterPropertiesSet() throws Exception {
  System.out.println("Calling after properties set method");
  
 }
 
 
 public IPayment getPayment() {
  return payment;
 }

 
 public void setPayment(IPayment payment) {
  this.payment = payment;
 }
}

IPayService interface

public interface IPayService {
 void performPayment();
}

IPayment interface

public interface IPayment {
 void executePayment();
}

CashPayment class

public class CashPayment implements IPayment{
 public void executePayment() {
  System.out.println("Perform Cash Payment "); 
 }

}

Class to run the code

public class App 
{
    public static void main( String[] args ){
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("appcontext.xml");
        IPayService bean = (IPayService) context.getBean("payServiceBean");
        bean.performPayment();
        context.close();
    }
}

Output

INFO: Loading XML bean definitions from class path resource [appcontext.xml]
Calling after properties set method
Perform Cash Payment 
Feb 28, 2016 5:54:12 PM org.springframework.context.support.ClassPathXmlApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@1f17ae12: startup date [Sun Feb 28 17:54:11 IST 2016]; root of context hierarchy
Calling destroy method

Custom init/destroy or @PostConstruct/@PreDestroy annotation

Using InitializingBean and DisposbleBean interfaces add Spring dependencies to your class so it is recommended to use either custom init and destroy method or @PostConstruct/@PreDestroy annotations. Note that both post-init and pre-destroy methods should have no arguments but they can throw Exceptions.

Infact you can use all 3 of them and in that case order in which these methods will be called is

  • Methods annotated with @PostConstruct
  • afterPropertiesSet() as defined by the InitializingBean callback interface
  • A custom configured init() method

Destroy methods are called in the same order:

  • Methods annotated with @PreDestroy
  • destroy() as defined by the DisposableBean callback interface
  • A custom configured destroy() method

So let's see an example where all three are called, in that case XML Configuration will look like -

 <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
 <!-- defining CashPayment bean -->
  <bean id="cashPaymentBean" class="org.netjs.exp.Spring_Example.CashPayment" />
 
  <!-- Defining PayServiceImpl bean and injecting payment bean -->
  <bean id="payServiceBean" class="org.netjs.exp.Spring_Example.PayServiceImpl" init-method="customInitMethod" destroy-method="customDestroyMethod">
      <property name="payment" ref="cashPaymentBean" />
  </bean>

Note that bean definition for CommonAnnotationBeanPostProcessor is added, this is required if you are using annotation.

Also with in the PayServiceImpl bean definition, two attributes init-method and destroy-method are added for init and destroy methods respectively.

And PayServiceImpl class will look like -

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class PayServiceImpl implements IPayService, InitializingBean, DisposableBean {
 
 private IPayment payment;
 
 public PayServiceImpl(){
  
 }
 public PayServiceImpl(IPayment payment){
  this.payment = payment;
 }
 
 public void performPayment() {
  payment.executePayment();
 }
 
 public void destroy() throws Exception {
  System.out.println("Calling destroy method"); 
 }

 public void afterPropertiesSet() throws Exception {
  System.out.println("Calling after properties set method"); 
 }
 
 // for init-method 
 public void customInitMethod(){
  System.out.println("Calling customInitMethod");
 }
 // for destroy-method 
 public void customDestroyMethod(){
  System.out.println("Calling customDestroyMethod");
 }
 
 @PostConstruct
 public void annoInitMethod(){
  System.out.println("Calling annoInitMethod");
 }
 
 @PreDestroy
 public void annoDestroyMethod(){
  System.out.println("Calling annoDestroyMethod");
 }
 public IPayment getPayment() {
  return payment;
 }

 
 public void setPayment(IPayment payment) {
  this.payment = payment;
 }
}

Output

Calling annoInitMethod
Calling after properties set method
Calling customInitMethod
Perform Cash Payment
Calling annoDestroyMethod
Calling destroy method
Calling customDestroyMethod

Note the order in which init and destroy methods are called.

Spring Aware Interfaces

Sometimes you may need some housekeeping information like the bean name, application context or servlet context, for which you need Spring framework objects. For that purpose Spring provides a number of aware interfaces that you can implement in your bean which will inject the required dependency.

Some of the most used aware interfaces are -

  1. ApplicationContextAware - This interface has setApplicationContext() method which will inject the applicationcontext dependency to the bean. Using it you can programmatically retrieve all the other bean definitions.
  2. BeanNameAware - This interface has setBeanName() method which provides the implementing class with a reference to the name defined in its associated object definition.
  3. BeanFactoryAware - This interface when implemented will inject BeanFactory. Using it you can get the bean definition and its attributes.
  4. ServletConfigAware, ServletContextAware to get ServletConfig and ServletContext valid only in in a web-aware Spring ApplicationContext

Example code

Let's create a bean that will implement some of these interfaces and provide some usage using the injected dependencies.

XML Configuration

Definition for new bean AwareBeanDemo is added

<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
<!-- defining CashPayment bean -->
<bean id="cashPaymentBean" class="org.netjs.exp.Spring_Example.CashPayment" />
 
<!-- Defining PayServiceImpl bean and injecting payment bean -->
<bean id="payServiceBean" class="org.netjs.exp.Spring_Example.PayServiceImpl" init-method="customInitMethod"
     destroy-method="customDestroyMethod">
      <property name="payment" ref="cashPaymentBean" />
</bean>

<bean id="awareBeanDemo" class="org.netjs.exp.Spring_Example.AwareBeanDemo" />

AwareBeanDemo class

import java.util.Arrays;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class AwareBeanDemo implements ApplicationContextAware, BeanNameAware, BeanFactoryAware{
 @Override
 public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
  System.out.println("In setBeanFactory");
  // Getting another bean and calling its method
  IPayService payService = (IPayService)beanFactory.getBean("payServiceBean");
  payService.performPayment();
 }
 
 @Override
 public void setBeanName(String name) {
  System.out.println("In setBeanName");
  System.out.println("Bean name - " + name);
  
 }
 
 @Override
 public void setApplicationContext(ApplicationContext appCtx)
   throws BeansException {
  System.out.println("In setApplicationContext");
  // Getting all the bean definitions
  String[] beanArr = appCtx.getBeanDefinitionNames();
  System.out.println( ""+ Arrays.toString(beanArr));
  
 }
}

Output

Calling annoInitMethod
Calling after properties set method
Calling customInitMethod
In setBeanName
Bean name - awareBeanDemo
In setBeanFactory
Perform Cash Payment 
In setApplicationContext
[org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#0, cashPaymentBean, payServiceBean, awareBeanDemo]
Calling annoDestroyMethod
Calling destroy method
Calling customDestroyMethod

Note that some of the output is coming from the init and destroy methods configured for other beans. Relevant output is highlighted,

That's all for this topic Life cycle of a bean in Spring. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Different bean scopes in Spring
  2. How to inject prototype scoped bean in singleton bean
  3. What is Dependency Injection in Spring
  4. Constructor-based dependency injection in Spring
  5. Spring example program using JavaConfig and Annotations
  6. Creating a Maven project in Eclipse

You may also like -

>>>Go to Spring tutorial page