What does it mean When it says object level lock and class level lock ?
When you lock on a static method you are locking on the Class object itself and there is one of these per ClassLoader. In your example,
public static synchronized int getCount(){
This is locking on the Counter.class object and is the same as:
public static int getCount() {
synchronized (Counter.class) {
}
If you are instead locking on a method that is not static then you are locking on the instance of the object that owns that method. In your example:
public synchronized void setCount(int count){
This is the same as locking on the particular Counter instance and is equivalent to:
public void setCount(int count){
synchronized (this) {
...
So if you have 2 Counter objects, counter1 and counter2, and 1 thread is calling counter1.getCount() and the other is calling counter2.getCount() at the same time, then they will both lock on the same Class object and one will block the other.
But if the 2 threads are instead calling counter1.setCount(...) and counter2.setCount() they will be locking on different objects -- counter1 and counter2 respectively. They will not block each other.
As mentioned, it is very bad form to have asymmetry on your setters and getters and it is unusual to have either be static.
Does that mean when getCount() get called another thread can't access setCount() since the whole class is locked ?
No. If getCount() is called, the Counter.class is locked and when setCount(...) is called counter1 or counter2 is locked. The only time a lock blocks a thread is when the same object has been locked by another thread. Just because there is a lock on Counter.class does not mean that there is some sort of uber-class lock. The only time that will block another thread is if it too locks on Counter.class.
I'd take a moment to read Sun's great documentation on how synchronized works.