When you declare a method for synchronization, for example:
public synchronized void foo() {
the compiler treats it as if you wrote this:
public void foo() { synchronized (this) {
In your example, you have one synchronized method and one unsynchronized. This means that only access to method1 will be blocked. Lock checks are only performed when entering the synchronized block, so calling method2 will not block.
To answer your two questions, in both cases, two threads will be allowed because they are not trying to get a lock on the same object. If you declare method2 for synchronization (or manually add a synchronized (this) block), then one thread will be forced to wait for another.
Remember: synchronization on an object does not interfere with other threads calling methods on this object. This only prevents another thread from appearing in the synchronized block with the same lock object.
By the way, it is often better to have an internal lock object rather than declare methods for synchronization, for example.
class Foo { private final Object LOCK = new Object(); public void doSomething() { synchronized (LOCK) {
Otherwise, I can violate thread safety by doing the following:
class MessEverythingUp { public MessEverythingUp(Foo foo) { synchronized (foo) { while (true) { System.out.println("Pwnd ur thread safety"); } } } }
Since I am locking the foo instance, your synchronized methods (with their implicit "synchronized (this)") will not be able to get the lock and will be locked forever. Most importantly, you cannot prevent this, because I can synchronize any object that I like. Obviously, the example is extreme, but you can get nasty, subtle bugs at a dead end if you are not careful about this.