Monday, 12 February 2018

Prove that ConcurrentHashMap class behaves like fail safe iterator?

Example -

import java.util.concurrent.ConcurrentHashMap; import java.util.Iterator; public class ConcurrentHashMapExample { public static void main(String[] args) { ConcurrentHashMap<String,String> premiumPhone = new ConcurrentHashMap<String,String>(); premiumPhone.put("Apple", "iPhone6"); premiumPhone.put("HTC", "HTC one"); premiumPhone.put("Samsung","S6"); Iterator iterator = premiumPhone.keySet().iterator(); while (iterator.hasNext()) { System.out.println(premiumPhone.get(iterator.next())); premiumPhone.put("Sony", "Xperia Z"); } } }

Does ConcurrentHashMap Iterator behaves like fail fast iterator or fail safe Iterator?

ConcurrentHashMap iterator behaves like fail safe iterator. It will not throw ConcurrentModificationException. 

Difference between Fail fast and fail safe iterator  or  Fail fast vs Fail Safe iterator is one of those questions which are  used to test your knowledge about the topic Concurrency.
Before we discuss in detail about fail safe iterator and fail fast iterator in addition to  their comparison , we should understand the term Concurrent Modification .

Can multiple threads read from the Hashtable concurrently ?

No multiple threads can not read simultaneously from Hashtable. Reason, the get() method of  Hashtable is synchronized. As a result , at a time only one thread can access the get() method .
It is possible to achieve full  concurrency for reads (all the threads read at the same time) in  ConcurrentHashMap by using volatile keyword.

Why ConcurrentHashMap does not allow null keys and null values ?

nulls aren't allowed in ConcurrentMaps (ConcurrentHashMaps, ConcurrentSkipListMaps) is that ambiguities that may be just barely tolerable in non-concurrent maps can't be accommodated. The main one is that if map.get(key) returns null, you can't detect whether the key explicitly maps to null vs the key isn't mapped. In a non-concurrent map, you can check this via map.contains(key), but in a concurrent one, the map might have changed between 
calls.

In simple words, 

if (map.containsKey(k)) { 
return map.get(k);
 } else { 
throw new KeyNotPresentException();
 } 

The code is like this : 
It might be possible that key k might be deleted in between the get(k) and containsKey(k) calls. As a result , the code will return null as opposed to KeyNotPresentException (Expected Result if key is not present). 

Can two threads update the ConcurrentHashMap simultaneously ?

Yes it is possible that two threads can simultaneously write on the ConcurrentHashMap. ConcurrentHashMap default implementation allows 16 threads to read and write in parallel. 
But in the worst case scenario , when two objects lie in the same segment or same partition, then parallel write would not be possible.

How ConcurrentHashMap works in Java

The constructor of ConcurrentHashMap looks like this :

public ConcurrentHashMap (int initialCapacity, float loadFactor, int concurrencyLevel)

So the above line  creates a new, empty map with the specified initial capacity, load factor and concurrency level.
where,
Important Parameters to consider from ConcurrentHashMap Constructor:

initialCapacity - the initial capacity. The implementation performs internal sizing to accommodate this many elements.
concurrencyLevel - the estimated number of concurrently updating threads. The implementation performs internal sizing to try to accomodate the internal group. 

As per concurrent Hashmap Api you will find the following constants.

static final int DEFAULT_INITIAL_CAPACITY = 16;
static final int DEFAULT_CONCURRENCY_LEVEL = 16;

initial capacity parameter and concurrency level parameters of ConcurrentHashMap constructor (or Object) are  set to 16 by default.

Thus, instead of a map wide lock, ConcurrentHashMap maintains  a list of 16 locks by default ( number of locks equal to the initial capacity , which is by default  16) each of which is used to lock on a single bucket of the Map.This indicates that 16 threads (number of threads equal to the concurrency level , which is by  default 16) can modify the collection at the same time , given ,each thread works on different bucket. So unlike hashtable, we perform any sort of operation ( update ,delete ,read ,create) without locking on entire map in ConcurrentHashMap.

Retrieval operations (including get) generally do not block, so may overlap with update operations (including putand remove). Retrievals reflect the results of the most recently completedupdate operations holding upon their onset. 

The allowed concurrency among update operations is guided by the optional concurrencyLevel constructor argument (default 16), which is used as a hint for internal sizing. The table is internally partitioned to try to permit the indicated number of concurrent updates without contention. Because placement in hash tables is essentially random, the actual concurrency will vary. Ideally, you should choose a value to accommodate as many threads as will ever concurrently modify the table. Using a significantly higher value than you need can waste space and time, and a significantly lower value can lead to thread contention

Why we need ConcurrentHashMap when we already had Hashtable ?

Hashtable provides concurrent access to the Map.Entries objects by locking the entire map to perform any sort of operation (update,delete,read,create). Suppose we have a web application , the overhead created by Hashtable  (locking the entire map) can be ignored under normal load. But under heavy load , the overhead of locking the entire map may prove fatal and may lead to delay response time and   overtaxing of the server.

  
This  is where ConcurrentHashMap comes to rescue. ConcurrentHashMap class is fully interoperable with Hashtable in programs that rely on its thread safety but not on its synchronization details. So the main purpose of this class is to provide the same functionality as of Hashtable but with a performance comparable to HashMap. 

Implementing two interfaces in a class with same method.

Two Interfaces With Same Method

Here is an example that shows a class implementing multiple interfaces with the same method.

If a type implements two interfaces, and each interface define a method that has identical signature, then in effect there is only one method, and they are not distinguishable.

interface I1 {
  abstract void method();
}
 
interface I2 {
  abstract void method();
}
 
public class MultipleInterfaces implements I1, I2 {
 
  @Override
  public void method() {
    System.out.println("hello world");
  }
 
  public static void main(String[] a) {
    MultipleInterfaces mi = new MultipleInterfaces();
    I1 i1 = new MultipleInterfaces();
    I2 i2 = new MultipleInterfaces();
    i1.method();
    i2.method();
  }
 
}
Output : $ java MultipleInterfaces
hello world
hello world

Saturday, 10 February 2018

Producer Consumer Design Pattern with Blocking Queue

In producer consumer design pattern a shared queue is used to control the flow and this separation allows you to code producer and consumer separately. It also addresses the issue of different timing require to produce item or consuming item. By using producer consumer pattern both Producer and Consumer Thread can work with different speed. 
Producer consumer pattern is everywhere in real life and depict coordination and collaboration. 

Real World Example- One person is preparing food (Producer) while other one is serving food (Consumer), both will use shared table for putting food plates and taking food plates. Producer which is the person preparing food will wait if table is full and Consumer (Person who is serving food) will wait if table is empty. table is a shared object here. On Java library. Executor framework itself implement Producer Consumer design pattern be separating responsibility of addition and execution of task.

Benefit of Producer Consumer Pattern-

1) Producer Consumer Pattern simple development. you can Code Producer and Consumer independently and Concurrently, they just need to know shared object.
2) Producer doesn't need to know about who is consumer or how many consumers are there. Same is true with Consumer.
3) Producer and Consumer can work with different speed. There is no risk of Consumer consuming half-baked item. In fact by monitoring consumer speed one can introduce more consumer for better utilization.
4) Separating producer and Consumer functionality result in more clean, readable and manageable code.

Java Example with BlockingQueue – 

BlockingQueue amazingly simplifies implementation of Producer-Consumer design pattern by providing out of box support of blocking on put() and take().

Step 1: Producer.java

class Producer implements Runnable {
    private final BlockingQueue sharedQueue;
    public Producer(BlockingQueue sharedQueue) {
        this.sharedQueue = sharedQueue;
    }
    @Override
    public void run() {
        for(int i=0; i<10; i++){
            try {
                System.out.println("Produced: " + i);
                sharedQueue.put(i);
            } catch (InterruptedException ex) {
                Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
}

Step 2: Consumer.java

class Consumer implements Runnable{
private final BlockingQueue sharedQueue;
public Consumer (BlockingQueue sharedQueue) {
this.sharedQueue = sharedQueue;
  }

  

    @Override

    public void run() {
        while(true){
            try {
                System.out.println("Consumed: "+ sharedQueue.take());
            } catch (InterruptedException ex) {
                Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }





Step 3: ProducerConsumerPattern.java

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ProducerConsumerPattern {

    public static void main(String args[]){
     //Creating shared object
     BlockingQueue sharedQueue = new LinkedBlockingQueue();
     //Creating Producer and Consumer Thread
     Thread prodThread = new Thread(new Producer(sharedQueue));
     Thread consThread = new Thread(new Consumer(sharedQueue));
     //Starting producer and Consumer thread
     prodThread.start();
     consThread.start();
    }
}
}





Output:

Produced: 0
Produced: 1
Consumed: 0
Produced: 2
Consumed: 1
Produced: 3
Consumed: 2
Produced: 4
Consumed: 3
Produced: 5
Consumed: 4
Produced: 6
Consumed: 5
Produced: 7
Consumed: 6
Produced: 8
Consumed: 7
Produced: 9
Consumed: 8
Consumed: 9

You see Producer Thread  produced number and Consumer thread consumes it in FIFO order because blocking queue allows elements to be accessed in FIFO.You see Producer Thread  produced number and Consumer thread consumes it in FIFO order because blocking queue allows elements to be accessed in FIFO.

Happy Learning !!