If you ask me one concept in Java which is so obvious yet most misunderstood, I would say the wait(), notify() and notifyAll() methods. They are quite obvious because they are the one of the three methods of total 9 methods from java.lang.Object but if you ask when to use the wait(), notify() and notfiyAll() in Java, not many Java developer can answer with surety. The number will go down dramatically if you ask them to solve the producer-consumer problem using wait() and notify(). Many will use if block instead of while loop, many others will get confused on which object they should call wait() and notify()method? Some of them even succeed in creating livelock, deadlock, and other multithreading issues.
One of the key difference between a static and a non-static method is that static method belongs to a class while non-static method belongs to the instance. This means you can call a static method without creating any instance of the class by just using the name of the class e.g. Math.random() for creating random numbers in Java. Often utility methods which don't use the member variables of the class are declared static. On the other hand, you need an instance of the class to call a non-static method in Java. You cannot call it without creating an object because they are dependent upon the member variables which has different values for different instances. One more important difference between the static and non-static method is that you cannot use a non-static member variable inside a static method, you cannot even call a non-static method from the static method, but the opposite is true e.g. you can call a static function from a non-static method in Java.
Double checked locking pattern is one of the interesting topics on Java Interviews. Earlier, it was asked to see if Java developer can write code using synchronized block or not and now it ask to gauge the candidate's understanding of concurrency, volatile and synchronization in Java. One of the simplest ways to write thread-safe Singleton was to make the getInstance() method synchronized but prior to JDK 1.6, a simple uncontented synchronization block was expensive and that lead many developers to write the getInstance() method of Singleton class using double-checked locking idiom. This was one of the clever idiom of that time which only uses synchronization when the Singleton object is created as seen in the following code and thus improves the performance of getInstance() method, which is used to retrieve the Singleton object.