Saturday, 27 December 2014

ConcurrentHashMap is very similar to HashTable but it provides better concurrency level.
You might know , you can synchonize HashTable using Collections.synchronizedMap(Map). So what is difference between ConcurrentHashMap and Collections.synchronizedMap(Map)

In case of Collections.synchronizedMap(Map), it locks whole HashTable object but in ConcurrentHashMap, it locks only part of it. You will understand it in later part.
Another difference is that ConcurrentHashMap will not throw ConcurrentModification exception if we try to modify ConcurrentHashMap while iterating it.

Lets take a very simple example. I
have a Country class, we are going to use Country class object as key
and its capital name(string) as value. Below example will help you to
understand, how these key value pair will be stored in ConcurrentHashMap.

Now
put debug point at line 23 and right click on project->debug as->
java application. Program will stop execution at line 23 then right
click on countryCapitalMap then select watch.You will be able to see
structure as below.

In above diagram, you can see each Segment class contains logically an HashMap.
Here size of table[](Array of HashEntry class) : 2ˆk >= (capacity/number of segments)
It stores a key value pair in a class called HashEntry which is similar to Entry class in HashMap.

When we say, ConcurrentHashMap locks only part of it.It actually locks a Segment. So if two threads are writing different segments in same ConcurrentHashMap, it allows write operation without any conflicts.

So Segments are only for write operations. In case of read operation, it allows full concurrency and provides most recently updated value using volatile variables.
Now as you understood internal structure of ConcurrentHashMap, it will be easier for you to understand put function.

Concept of ConcurrencyLevel:

While creating a ConcurrentHashMap object, you can pass ConcurrencyLevel in the constructor. ConcurrencyLevel defines"Estimated number of threads going to write to the ConcurrentHashMap". Default ConcurrencyLevel is 16. That is why, we got 16 Segments objects in above created ConcurrentHashMap.
Actual number of Segment will be equal to next power of two defined in ConcurrencyLevel.For example:
Lets say you have defined ConcurrencyLevel as 5, so 8 Segments object will be created as 8=2^3 so 3 higher bits of Key will be used to find index of the segmentAnother example: You want 10 threads should be able to access ConcurrentHashMap concurrently, so you will define
ConcurrencyLevel as 10 , So 16 Segments will be created as 16=2^4 so 4 higher bits of Key will be used to find index of the segment

When we add any key value pair to ConcurrentHashMap, following steps take place:

In ConcurrentHashMap, key can not be null. Key's hashCode method is used to calculate hash code

Key 's HashCode method may be poorly written, so java developers have added one more method hash(Similar to HashMap) , another hash() function is applied and hashcode is calculated.

Now we need to find index of segment first, For finding a segment for given key, above SegmentFor method is used.

After getting Segment, we use segment's put method.While putting key value pair in Segment, it acquires lock, so no other thread can enter in this block and then it finds index in HashEntry array using hash &(tab.length-1).

If you closely observe, Segment's put method is similar to HashMap's put method.

putIfAbsent:

You want to put element in ConcurrentHashMap only when if it does not have Key already otherwise return old value. This can be written as:

So we tried to add String "Arpit" twice, but as HashSet does not allow duplicate value, it will add "Arpit" once in HashSet

In case of Custom Objects:
For understanding how HashSet will work in case of custom objects, you need to understand hashcode and equals method in java.Lets create a class called Country and implement only equals method in it.

Now you must be wondering even through two objects are equal why HashSet contains two values instead of one.This is because First HashSet calculates hashcode for that key object, if hashcodes are same then only it checks for equals method and because hashcode for above two country objects uses default hashcode method,Both will have different memory address hence different hashcode.
Now lets add hashcode method in above Country class

So from above code, It is clear that HashSet uses HashMap for checking duplicate elements.As we know that in HashMap , key should be unique. So HashSet uses this concept, When element is added to HashSet, it is added to internal HashMap as Key.This HashMap required some value so a dummy Object(PRESENT) is used as value in this HashMap.
PRESENT is dummy value which is used value for internal map.
Lets see add method:

map.put(e,PRESENT) will return null, if element not present in that map. So map.put(e, PRESENT) == null will return true ,hence add method will return true and element will be added in HashSet.

map.put(e,PRESENT) will return old value ,if element is already present in that map. So map.put(e, PRESENT) == null will return false, hence add method will return false and element will not be added in HashSet.

Friday, 11 July 2014

One of the common interview question is "What is difference between sleep and wait in java".Before we actually see differences,let me give you brief introduction of both.

sleep

It causes current executing thread to sleep for specific amount of time.

Its accuracy depends on system timers and schedulers.

It keeps the monitors it has acquired, so if it is called from synchronized context, no other thread can enter that block or method.

If we call interrupt() method , it will wake up the sleeping thread.

synchronized(lockedObject) {
Thread.sleep(1000); // It does not release the lock on lockedObject.
// So either after 1000 miliseconds, current thread will wake up, or after we call
//t. interrupt() method.
}

wait

It causes current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object

It must be called from synchronized context i.e. from block or method.It means before wait() method is called,current thread must have lock on that object.

It releases lock on the object on which it is called and added to wait list, so another thread can acquire lock on the object.

synchronized(lockedObject) {
lockedObject.wait(); // It releases the lock on lockedObject.
// So until we call notify() or notifyAll() from other thread,It will
// not wake up
}

sleep vs wait:

Parameter

wait

sleep

Synchonized

wait should be called from synchronized context i.e. from block or method, If you do not call it using synchronized context, it will throw IllegalMonitorStateException

It need not be called from synchronized block or methods

Calls on

wait method operates on Object and defined in Object class

Sleep method operates on current thread and is in java.lang.Thread

Release of lock

wait release lock of object on which it is called and also other locks if it holds any

Thursday, 10 July 2014

In this post, we will see how to find prime factors of a number in java.
A prime number is a natural number greater than 1 that has no positive divisors other than 1 and itself.
The prime factors of a number are all of the prime numbers that will exactly divide the given number.
For example-
Prime factor of 15 = 3,5
Prime factor of 48=2,2,2,2,3

You must be wondering we are not checking whether loop variable i is prime or not But you don't need to do this because in any loop, number has been already divided by 2 to i-1 so i can only be divisor if it is prime.

Blogroll

Disclaimer

Most of the content in this blog has been written by me. All the examples/screenshots are my work. However I have taken extensive help of google and roseindia for my work. Hope you enjoy learning this content.