While its guaranteed by JLS that a class will be loaded when there is a need of static initialization.
When a Class is initialized in Java
After class loading, initialization of class takes place which means initializing all static members of class. A Class is initialized in Java when :
1) an Instance of class is created using either new() keyword or using reflection using class.forName(), which may throw ClassNotFoundException in Java.
2) an static method of Class is invoked.
3) an static field of Class is assigned.
4) an static field of class is used which is not a constant variable.
5) if Class is a top level class and an assert statement lexically nested within class is executed.
How Class is initialized in Java
1) Classes are initialized from top to bottom so field declared on top initialized before field declared in bottom
2) Super Class is initialized before Sub Class or derived class in Java
3) If Class initialization is triggered due to access of static field, only Class which has declared static field is initialized and it doesn't trigger initialization of super class or sub class even if static field is referenced by Type of Sub Class, Sub Interface or by implementation class of interface.
4) interface initialization in Java doesn't cause super interfaces to be initialized.
5) static fields are initialized during static initialization of class while non static fields are initialized when instance of class is created. It means static fields are initialized before non static fields in Java.
6)non static fields are initialized by constructors in Java. sub class constructor implicitly call super class constructor before doing any initialization, which guarantees that non static or instance variables of super class is initialized before sub class.
Comparator vs Comparable in Java Comparators and comparable in Java are two interfaces which is used to implement sorting in Java. It’s often required to sort objects stored in any collection classes like ArrayList, HashSet or in Array and that time we need to use either compare() or compareTo() method defined in java.util.Comparatorand java.lang.Comparable.
1) Comparator in Java is defined in java.util package while Comparable interface in Java is defined injava.lang package, which very much says that Comparator should be used as an utility to sort objects whichComparable should be provided by default.
4) Comparable in Java is used to implement natural ordering of object. In Java API String, Date and wrapper classes implements Comparable interface.Its always good practice to override compareTo() for value objects.
5) If any class implement Comparable interface in Java then collection of that object either List or Array can be sorted automatically by using Collections.sort() or Arrays.sort() method and object will be sorted based on there natural order defined by CompareTo method.
6)Objects which implement Comparable in Java can be used as keys in a SortedMap like TreeMap or elements in aSortedSet for example TreeSet, without specifying any Comparator.
When to use Comparator and Comparable in Java
1) If there is a natural or default way of sorting Object already exist during development of Class than use Comparable. On the other hand if an Object can be sorted on multiple ways and client is specifying on which parameter sorting should take place than use Comparator interface.
2) Some time you write code to sort object of a class for which you are not the original author, or you don't have access to code. In these cases you can not implement Comparable and Comparator is only way to sort those objects.
3) Beware with the fact that How those object will behave if stored in SorteSetor SortedMap like TreeSet and TreeMap. If an object doesn't implement Comparable than while putting them into SortedMap, always provided correspondingComparator which can provide sorting logic.
4) Order of comparison is very important while implementing Comparable or Comparator interface.
As per Javadoc, ReentrantLock is mutual exclusive lock, similar to implicit locking provided bysynchronized keyword in Java, with extended feature like fairness, which can be used to provide lock to longest waiting thread.
Difference between ReentrantLock and synchronized keyword in Java
main difference between synchronized and ReentrantLock is ability to trying for lock interruptibly, and with timeout. Thread doesn’t need to block infinitely, which was the case with synchronized. Let’s see few more differences between synchronized and Lock in Java.
1) Another significant difference between ReentrantLock and synchronized keyword is fairness. synchronizedkeyword doesn't support fairness. Any thread can acquire lock once released, no preference can be specified, on the other hand you can make ReentrantLock fair by specifying fairness property, while creating instance of ReentrantLock. Fairness property provides lock to longest waiting thread, in case of contention.
2) Second difference between synchronized and Reentrant lock is tryLock()method. ReentrantLock provides convenient tryLock() method, which acquires lock only if its available or not held by any other thread. This reduceblocking of thread waiting for lock in Java application.
3) One more worth noting difference between ReentrantLock and synchronized keyword in Java is, ability to interruptThread while waiting for Lock. In case of synchronized keyword, a thread can be blocked waiting for lock, for an indefinite period of time and there was no way to control that. ReentrantLock provides a method called lockInterruptibly(), which can be used to interrupt thread when it is waiting for lock. Similarly tryLock() with timeout can be used to timeout if lock is not available in certain time period.
4) ReentrantLock also provides convenient method to get List of all threads waiting for lock.
Benefits of ReentrantLock in Java
1) Ability to lock interruptibly.
2) Ability to timeout while waiting for lock.
3) Power to create fair lock.
4) API to get list of waiting thread for lock.
5) Flexibility to try for lock without blocking.
Disadvantages of ReentrantLock in Java Major drawback of using ReentrantLock in Java is wrapping method body inside try-finally block,which makes code unreadable and hides business logic. Another disadvantage is that, now programmer is responsible for acquiring and releasing lock, which is a power but also opens gate for new subtle bugs, when programmer forget to release the lock in finally bloc
Code:
publicReentrantLock(booleanfair){
sync=fair?newFairSync():newNonfairSync();
}
* <p>Acquires the lock if it is not held by another thread and returns
* immediately, setting the lock hold count to one.
* <p>If the current thread already holds the lock then the hold
* count is incremented by one and the method returns immediately.
publicvoidlock(){
sync.lock();
}
Acquires the lock unless the current thread is interrupted.
Acquires the lock if it is not held by another thread and returns immediately, setting the lock hold count to one.
If the current thread already holds this lock then the hold count is incremented by one and the method returns immediately.
If the lock is held by another thread then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of two things happens:
If the current thread is the holder of this lock then the hold count is decremented. If the hold count is now zero then the lock is released. If the current thread is not the holder of this lock then IllegalMonitorStateException is thrown.