unj2
unj2

Reputation: 53481

Am I correct in my assumption about synchronized block?

I have a method shout() with a synchronized block.

  private void shout(){
    System.out.println("SHOUT " + Thread.currentThread().getName());
    synchronized(this){
      System.out.println("Synchronized Shout"  + Thread.currentThread().getName());
      try {
        Thread.sleep(50);
      }
      catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println("Synchronized Shout"  + Thread.currentThread().getName());
     }
  }

If I have two Threads that run this method, am I correct in assuming that the two "Synchronized Shout" will always appear one after the other? There can be no other statements in between the "Synchronized Shout"?

Upvotes: 1

Views: 356

Answers (3)

mdma
mdma

Reputation: 57707

When two or more threads are running against the same instance, then the SHOUT can appear anywhere, because it's outside the synchronized block, and thus unguarded. The "synchronized shout"s will always appear strictly in order, with no synchornized shout from another thread getting in between and affecting the order.

Upvotes: 0

sjlee
sjlee

Reputation: 7866

Since the line that prints "SHOUT..." does not require a lock, it can appear at any point. Thus, even if one thread is holding the lock, another thread may come in and print "SHOUT...".

The following code shows the interleaving:

public class Interleave {
  public static void main(String[] args) throws Throwable {
    Task task = new Task();
    Thread t1 = new Thread(task);
    Thread t2 = new Thread(task);
    t1.start();
    Thread.sleep(25);
    t2.start();
  }

  private static class Task implements Runnable {
    public void run() {
      shout();
    }

    private void shout() {
      System.out.println("SHOUT " + Thread.currentThread().getName());
      synchronized (this) {
        System.out.println("Synchronized Shout "  + Thread.currentThread().getName());
        try {
          Thread.sleep(50);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        System.out.println("Synchronized Shout "  + Thread.currentThread().getName());
      }
    }
  }
}

It prints out

SHOUT Thread-0
Synchronized Shout Thread-0
SHOUT Thread-1
Synchronized Shout Thread-0
Synchronized Shout Thread-1
Synchronized Shout Thread-1

Upvotes: 2

Tom Hawtin - tackline
Tom Hawtin - tackline

Reputation: 147124

So long as the this reference is the same. If you run the code on two different objects, the lock will have no effect.

Note, if you were to use Object.wait on this instead of calling Thread.sleep to delay, then the lock would be removed (and reacquired before moving on).

Upvotes: 2

Related Questions