Saturday, August 3

All about annotations in java

                      All about  annotations in java 

What is annotation ?

Annotation is introduced in java 1.5. It is used to apply meta information on source code in source code file itself

What is the purpose of annotation ?

Annotation help in providing meta information to code source file at as per desired Retention 
policy

What is retention policy?

Retention policy defines at what time do we want to apply the meta information in our source code. Java provides three different levels of applying meta information.
1. SOURCE
2. CLASS
3. RUNTIME 

Source : Meta information is applied at in source code only. At compile time and runtime it won't be available 

Example : @override , @suppress warning

CLASS : Meta information is applied in .class file i.e. bytecode 


RUNTIME : Meta information is applied at runtime .

Example : @deprecated

What is the advantage? 

It helps binding meta information with source code itself with required control . 
It removes dependency on xml file . Annotation replaces XML. Yes , Annotation can be used to apply the same meta information on source what earlier used to be done by XML 

Are there some in built annotation in java?

Yes there are For Example:

 : @Suppress 
   @override
   @deprecated

What is basic syntax of annotation ? 

at minimum it requires combination of @ and interface 

For example 

public @interface myAnnot{
}

Here myAnnot is the annotation defined. This much is sufficient to define a well qualified complete annotation.

How do we apply an annotation?

If you have seen some code written java 1.5 onwards you might have seen something like 


@Override
void mySuperMethod() { ... }


What is @override doing here. This is an annotation saying that this method is overridden. And if any override rule is violated It helps compiler is raising compilation error. If annotation won't have been there compiler would have completely ignored the error and we would have been in big time trouble at runtime. Identifying error at runtime can be very costly and very tedious task to identify.


Similarly 

@SuppressWarnings(value = "unchecked")
void myMethod() { ... }

@suppress annotation is basically instructing compiler to suppress the unchecked warning . After applying this compiler won't highlight any unchecked code warning.

Can we write our own annotation?
Absolutely. myAnnot above is an example of user defined annotation. 

Below is another example of annotation . We generally use this to with our source file.



@interface CodeInfor{
   String author();
   String date();
   String lastModified() default "mycompany";
   String lastModifiedBy() 
  }

What are the rules that are applied on annotations?

 annotation is defined using interface as keyword preceding with @ special character.


Can annotation be applied on another annotation?

Absolutely. @Retention is an example of that . This is discussed above

other useful annotations that are applied on other annotations are : 

@Documented ,
 @Target,@Inherited , 
@Repeatable 

@Target defines at what type this annotation will be applied for example :

constructor 
field
method
parameter

With that we can define at what part of the code a specific annotation should be applied.

Java provides extensive API to identify what annotations are applied at a specific class , method , constructor, variable or parameter. 





Tuesday, July 30

for-each loop limitations

Three scenarios where you can not use for each loop

for each loop provides a way to iterate over a collection of objects of class implementing Iterable interface. It provides little better performance as compared to traditional for loop and is a cleaner way to iterate over a collection. It removes the chances of error that could be introduced while iterating over multiple collection through traditional for loop . Developer could got wrong in updating and traversing over changing indexes of objects in collection . This kind of error is unlikely in for each loop

But there are situations where for-each can't be used

1. If you want to remove an element of collection while iterating for-each provides no remove method. So you can't use it in such scenario

2. If you want to replace some element in collection while iterating over collection You can't do that as there is no replace or update method here neither you have control to access the element with its index value .

3.A situation where you are working in parallel with multiple collections have to do a lot of operation with current index value of iterable collection. You don't have access to element index while iterating with for-each loop So you can't use it.


Semaphore in java concurrency package

What is Semaphore?

Let us understand simple concept of semaphore with an real time practical example .

Everyone at some point of time would have worked on database connection pool. In connection pool we maintain maximum number of connections allowed. So how do we control that. 

Let's say maximum number of allowed connection for a database is 10 and If 10 connection exhaust next thread will have to wait until one of the connection gets released. 

Semaphore provides a very simple way to implement this . 

Semaphore is nothing but a way of code synchronization with a specific counter. 

Let's understand this with a code snippet 

Public class ConnectionManager {

Semaphore sem =new Semaphore(10);

    public Connection getConnection(){
                 sem.acquire();
                 useConnection();
                 sem.release();
           }

    public void useConnection(){
          }



Through semaphone we maintain the counter limit for connection as 10. Any thread that needs database connection will invoke getConnection() method . 
When sem.acquire() is invoked sem counter is decreased by one . Everytime sem.acquire() method is invoked sem counter is decreased by one. So every thread that will invoke getConnection() method will decrease the sem counter by one.

When counter reaches 0 , sem.acquire() returns false and connection can not be obtained as maximum limit of allowed connection is already reached. 

Now every time sem.release() method is invoked sem counter is increased by one . This means it makes the connection available for reuse . So Client may continue trying to acquire the connection and may succeed if sem counter value become greater than 0

So semaphore helps in managing the maximum no of permits through a counter . Its value changes with critical area access acquire and release. 

That's how semaphore works. It just a better and clean way (with much lesser lines of code) to implement synchronization for situations where a counter based implementation can be useful.


Atomic variables in java


Atomic variables are introduced in java in version 5.0

To understand why atomic variables are introduced lets get through a piece of code 

Public class Calculator {
int i=0;
public int get (){
return i++;
   }
}

This is pretty simple code and work as expected in single threaded environment. 

But does it behave the same way in multithreaded environment as well.

i++ is not a single step operation instead it happens in three steps

1) value to be updated is read
2) manipulation is performed
3) new value is set in variable 

So if mutiple threads call get method simultaneously they will result in operating over i in inconsistent state . one thread might be in progress of incrementing the value and at same time other thread might access the variable and perform increment on same value . So multi step operation results in highly inconsistent data state .

How do we resolve this problem ?

Way to resolve this problem is to allow only one thread at a time to access get methods and perform all three steps completely only then allow other thread to access the method. 

How do we achieve that ? 

Way to achieve that is synchronization. 

public int synchronized get (){
return i++;
}

This will allow only one thread to access method at one time . Thread will take the lock on the object and will release lock while exiting the method . then other thread will take the lock. 

Here multiple threads are working in sequential manner. Although data inconsistency issue is resolved But it has degraded the performance a lot . Now multiple threads are taking as much time as many number of threads execute the get() method.

Way to overcome that is atomic variables . 


 JVM compiles these classes with the better operations provided by the hardware machine, CAS or a Java implementation of the operation using a lock. 

Atomic classes in java are 


  • AtomicInteger
  • AtomicLong
  • AtomicBoolean
  • AtomicReference


All these classes supports compare-and-set (via the compareAndSet() method) . The setters operations are implemented using compareAndSet. These classes supports multi-threaded access and have a better scalability than synchronizing  the operations.

what is compareAndSet?

Quickly read that here 

http://efectivejava.blogspot.in/2013/07/what-is-compare-and-swap-and-compare.html

Here is how we can rewrite our get() method using an AtomicInteger :


public class Calculator{

    private final AtomicInteger var= new AtomicInteger(0);
          public int get(){
            return  var.incrementAndGet();
      }
}

The incrementAndGet()  method is  provided by the AtomicLong and AtomicInteger classes. there are many other methods for other operations like decrementandget() , getandset();

This is faster than the synchronized one and is also thread safe.

Monday, July 29

What is reifiable and non-reifiable java

What is reifiable and non-reifiable java ?

a reifiable type is one whose runtime representation contains same information than its compile-time representa-tion

a non-reifiable type is one whose runtime representation contains less information than its compile-time representa-tion

Arrays are reifiable as arrays remains as it is at runtime While generic information attached with List is erased at runtime by erasures

So List<String> list=new ArrayList<String>

at runtime will be

List list=new ArrayList();

all generic information is erased. This is done to support the legacy code that is written without using generics.

But in case of arrays

Object[] ojb=new Object[0]

will remain the same at runtime as well. Generics are not mixed with arrays.