A question on Java multi-threading A question on Java multi-threading multithreading multithreading

A question on Java multi-threading


Only the method with the keyword synchronized holds a lock for this object when a thread is running in that method.
Had both method 1 and method 2 been declared as synchronized, one thread would block the other even though they are trying to run different methods.
In your example only 1 method is blocking by an implicit lock.
As a result t1 and t2 can be running concurrently in method 1 and method 2 (or vice versa).
Only when trying to access method 1, a t1 or t2 would block if the lock has already been acquired


When you declare a method to be synchronized, e.g.:

public synchronized void foo() {    // Do something}

the compiler treats it as though you had written this:

public void foo() {    synchronized (this) {        // Do something    }}

In your example you have one synchronized method and one non-synchronized. This means that only access to method1 will be locked. Locking checks are only done on entry to a synchronized block, so calling method2 will not trigger any locking.

To answer your two questions, then, in both cases the two threads will be allowed to proceed because they are not trying to obtain a lock on the same object. If you declare method2 to be synchronized (or manually add a synchronized (this) block) then one thread will be forced to wait for the other.

Remember: synchronizing on an object does not prevent other threads calling methods on that object. It only prevents another thread entering a synchronized block with the same lock object.

Incidentally, it's often better to have an internal lock object rather than declaring methods to be synchronized, e.g.

class Foo {    private final Object LOCK = new Object();    public void doSomething() {        synchronized (LOCK) {            // Whatever        }    }}

Otherwise I can break your thread-safety by doing this:

class MessEverythingUp {    public MessEverythingUp(Foo foo) {        synchronized (foo) {            while (true) {                System.out.println("Pwnd ur thread safety");            }        }    }}

Since I'm locking the instance of foo, your synchronized methods (with their implicit "synchronized (this)") will not be able to obtain a lock and will block forever. Most importantly, you cannot prevent this because I can synchronize on whatever object I like. Obviously the example is extreme but you can get nasty, subtle deadlock bugs if you're not careful about this sort of thing.


In both cases, the second thread will be given permission to execute its method.

Since only one of these two methods contains the synchronized keyword, both of these methods can be executed simultaneously. The restriction is that only one method with that keyword can be executed at any given time, because executing that method requires a lock on the object. A thread without the keyword requires no lock and will always be allowed to execute regardless of the object being locked.

I also assume here that the 1000 lines of code in method2 does not contain a block like this:

synchronized (this) {}

If it does, then the results will be different.

  1. t2 will be allowed to start executing the method. When it hits the synchronized line, it will wait for t1 to finish method1 and release its lock before continuing.
  2. t2 will be allowed to start executing the method so long as t1 is not within the synchronized code block. If it is, t2 will wait until t1 exits the block and releases the lock before beginning. If t1 has not yet entered the synchronized block, then t2 will acquire the lock, and t1 will wait as soon as it gets to the synchronized code block until t2 completes the method and releases the lock.