James Raitsev
James Raitsev

Reputation: 96531

Differences between synchronized(this) and synchronized(objectReference)

I'd like to better understand the mechanics of what actually happens when thread enters the synchronized(this) block vs synchronized(someObjectReference) block.

    synchronized (this) {
        // Statement 1
        // Statement 2
    }

    synchronized (someObjectReference) {
        // Statement 1
        // Statement 2
    }

As i understand it: (am i missing something? am i wrong?)

What other mechanics are there please?

    synchronized (objectReference) {
        // Statement 1 dealing with someObjectReference
        // Statement 2 not dealing with someObjectReference
    }

In the example above, does it make any sense adding statements not dealing with mutex into the synchronized block?

Upvotes: 0

Views: 274

Answers (4)

unholysampler
unholysampler

Reputation: 17341

One important thing to note about synchronizing on this deals with visibility. Lets say you have a class A and it synchronizes on this. Any code that uses A has a reference to the object A is using to lock on. This means it is possible for a user of A to create a deadlock if they also lock on the A instance.

public class A implements Runnable {
  public void run() {
    synchronized (this) {
      // something that blocks waiting for a signal
    }
    //other code
  }
}

public class DeadLock {
  public void deadLock() {
    A a = new A();
    Thread t = new Thread(a);
    t.start();

    Thread.sleep(5000); //make sure other thread starts and enters synchronized block
    synchronized (a) {
      // THIS CODE BLOCK NEVER EXECUTES
      // signal a
    }
  }
}

Where as, if you always synchronize on a private member variable, you know that you are the only one using that reference as a lock.

Upvotes: 0

Rajesh
Rajesh

Reputation: 3034

Synchronize basically means program request to take a lock on the specified object...If a Thread is not able to enter any synchronized block then that means any other thread has already taken lock on the specified object..BLock of code specify that inside this region a thread can enter if lock is successfully acquired..

 In both cases, only 1 thread can access synchronized block at a time

--Depend on the object to be locked availability

Upvotes: 0

cporte
cporte

Reputation: 2191

In both cases, only 1 thread can access synchronized block at a time

Not really. For exemple, when synchronizing on "this", 2 threads can access to the same block if they have 2 different instances of the same class. But yes, for one instance, there will be only one access to the block. And there will also have only one acess to any synchronized block on this

"Synchronized" means that only 1 thread can have access to any synchronized block on the same instance. So if you have 2 synchronized block in 2 different source files, but on the same instance, if one thread is inside one of those blocks, another thread cannot access to both synchronized block

About "what to do within a synchronized block" : do only things dealing with the synchronized object. Any other instruction that doesn't need synchronization will lock the ressource for nothing, an potentially create a bottleneck

Upvotes: 1

Louis Wasserman
Louis Wasserman

Reputation: 198471

There's only a difference when you mix the two together.

The single, basic rule of synchronized(foo) is that only one thread can be in a synchronized(foo) block for the same foo at any given time. That's it. (The only caveat maybe worth mentioning is that a thread can be inside several nested synchronized(foo) blocks for the same foo.)

If some code is inside a synchronized(foo) block, and some code is inside a synchronized(bar) block, then those pieces of code can run simultaneously -- but you can't have two threads running code in synchronized(foo) blocks simultaneously.

Upvotes: 2

Related Questions