Monday, July 22

Synchronized HashMap versus Concurrent hashMap

1. Synchronized Map locks the entire Map While concurrent HashMap work on stripped lock principal. It divided the hash bucket in 16 different sub parts. So if one thread is reading one part of the bucket and other thread is writing on a different part , these execution will not be halted. Thus it gives better performance.


==================================================================
2. Concurrent HashMap does not perform well in case size() or contains() methods are invoked.As it requires synchronization on entire hash bucket.




======================================================================
3. If we need to make two operation on synchronized hashMap , calling code needs to be synchronized While same is not required in case of concurrent hashmap.

For example :

if(!synchronizedList.contains(element)){ ---------------------- (1)

     synchronizedList.add(element); -------------------------------(2)

}



this code is quiet common but not thread safe at all. 1 and 2 are synchronized but the time between the call to 1 and then to 2 there is a possibility that thread contention can occur and our thread which did the contains call may change state. To fix this we need to make this block synchronized in our code. Similar issues happen with synchronized map too.



synchronized(synchronizedList){

     if(!synchronizedList.contains(element)){

          synchronizedList.add(element);

    }

}

ConcurrentHashMap solves ths problem by providing atomic putIfAbscent method calls which essentially does this job only.



========================================================================

4. Synchronized hashMap is fail safe So we need to exclusively synchronize to avoid concurrent modification exception. This will affect overall performance. Concurrent HashMap is lenient on this . It allows to iterate over the map even while are part of bucket is being updated. 


=======================================================================

Item 24 : Eliminate unchecked warnings

What is unchecked warning ?

While you compile a piece of code , It is possible that It compile with warnings.You may completely ignore these warnings to get your code compiled.
What is the threat in ignoring warnings?

ClassCast Exception. Warning suggests you How you are leaving your code with risk of ClassCast exception.So It is must to resolve all warnings.
Does @suppresswarning removes the risk?

Not at all. It makes the situation more dangerous.If you add @supprresswarning on method level to avoid a specific warning It will curb all warnings that will ever come on any line of code in your method Even if those lines are added in furuture.
So you are making your code less confident and unsafe.
So what's the remedy?

1. Resolve all warnings. (recommended)

2. Reduce the scope of @suppresswarning (if you apply that ). It should be minimum, best is to use it to jusr suppress the warnings only on one line of code On which it is applied. There you get chance to resolve warnings coming in otehr part of method or class. Never use it on class or method level unless it has just one line of code.

So to make your code completely free from risk of ClassCast Exception eliminate all unchecked warnings. Otherwise keep the scope of warning supprression to minimum

Sunday, July 21

Item 23 : Don't use raw type in new code

What is new code?

Code written using release 1.5 onwards in new code. Generics are included in release 1.5
Why should we switch to generic type?

Generic types provide compile time type safety and it's good in programming to know the error as early as possible.
ClassCast exceptions that generally are unraveled only at runtime type would know detected at compile time itself if Generic types are followed.

For example :

1. List list ; // List of Horse.

2. list.add(new horse());
3. list.add(new Dog());

4. while(list.hasNext()){

5. Horse horse = list.next();

6. }


Line 5 , will throw ClassCasException as It tries to assign an instance of Dog class to Horse Type.

list is just the list of horses but mistakenly Dog is also added to that. Compiler did not compliant while adding Dog as the type of list is not specified . It's raw type list. Now the mistake skipped by Compiler costs heavily at runtime and program failed due to ClassCast Exception.

Now the Question Is Could that be avoided. Could we smell the the error earlier?

Yes , we could ask the compiler to detect the menace just by using generic type list.

1. List<Horse> list ; // List of Horse.

2. list.add(new horse());
3. list.add(new Dog());

4. while(list.hasNext()){

5. Horse horse = list.next();

6. }

at Line no 1 , list is defined to be Horse type So compiler already knows the type of list . It would complain as soon as you add Dog to the list.

Thus using generic type enforce the type safety check at compile time itself and there It can be corrected and heavy runtime burst is avoided.

Friday, July 19

Item 71: Use lazy initialization judiciously



What is lazy initialization ?


 How is it different from normal initialization?

Lazy initialization adds delay to the time an instance or static variable gets initialized.


 How much delay?

Initialization can be delayed as long as it is not required in our execution.

Why would you delay that ?

There might be a possibility that instance might not be required at all. In that case there is not only a performance gain but also you are avoiding allocating memory unnecessarily.

Then Why do you need to be Judicious? Why can't we consider it as a default principal to use lazy initialization in every case.

Lets understand that with a code snippet

Public class Car {

        private Tyre tyre ;

     public Tyre getTyreInstance(){

              if(tyre==null){

                 tyre=new Tyre()
              }

              return tyre;

           }
}

What is happening here. First we are checking If instance is null or not . So this execution of If statement is happening in every case . If there are too many instances required tyre are required multiple execution of this if check may deteriorates the overall performance instead of increasing depending upon how much complexity is involved in instance initialization. On the other hand if there are only a few instances of tyre are required , performance save on part of lazy initialization may be much more than that of performance loss in if statement execution.

So we need to be highly judicious while using lazy initialization.

Now how will we decide practically whether to use it or not in a given scenario. Simple answer is measure the performance with and without lazy initialization ,compare and use the option resulting in overall better performance.

Effective java Simplified

Thursday, July 11

Effective java : Item 66 : Synchronized access to shared mutable data




                  Synchronized access to shared mutable data

What is Mutable Data? : data that can be modified.

Shared ?: Being accessed and updated by multiple threads

What is Synchronized access? :

Synchronization is a keyword used  with a method or block of code to restrict the access of shared data to only one thread at one time. Essentially it provides locking mechanism .

But , Is synchronization all about locking and restriction. NO

Another very important behavior Synchronization provides is visibility. 

What is visibility ?

When a thread makes a change to shared data  this change is not always visible to other threads working on same data If shared data is not synchronized

Let’s take an example :

Public class Climate {

Boolean stop;



Thread rain =new Thread(new Runnable (



Public void run(){



While(!stop){



Keepraining();



}



);)



Rain.start();



Stop=true;





}

Here there are two threads .
 1. Main thread
 2) rain thread spawned from main thread.  

 You may think that rain thread will execute once or twice and will stop as soon as  stop=true is executed in main thread. But this may not be the case every time , in every environment .Instead rain thread keeps working on its cached data and any change in the data does not become visible to rain thread unless it is explicitly brought in sync. 

                     So synchronization bring every participating thread in sync. To make this program run as expected every time in every environment value of stop variable should be accessed /mutated with in a synchronize block.

Write need to be synchronized for mutually exclusive access to shared data AND read needs to be synchronized so that any change in the data from any thread is visible to the thread currently reading it .

So Synchronization is important for two very strong features in multi - threaded programming


  •      Locking
  •    Visibility



 Please comment/question to discuss it further: