by BehindJava

How to avoid synchronized(this) in Java

Home » java » How to avoid synchronized(this) in Java

This is a quick tutorial on avoiding synchronized(this) in Java.

Threads and shareable entities

It is possible for multiple threads to access same entity, for eg multiple connectionThreads sharing a single messageQueue. Since the threads run concurrently there may be a chance of overriding one’s data by another which may be a messed up situation.

So we need some way to ensure that shareable entity is accessed only by one thread at a time. (CONCURRENCY).

All synchronized methods within the same class use the exact same lock, which reduces throughput.

Synchronized block

synchronized() block is a way to ensure concurrent access of shareable entity.

First, a small analogy

Suppose There are two-person P1, P2 (threads) a Washbasin (shareable entity) inside a washroom and there is a door (lock).

Now we want one person to use washbasin at a time.

An approach is to lock the door by P1 when the door is locked P2 waits until p1 completes his work P1 unlocks the door then only p1 can use washbasin.

Syntax

synchronized(this)
{
  SHARED_ENTITY.....
}

“this” provided the intrinsic lock associated with the class (Java developer designed Object class in such a way that each object can work as monitor). Above approach works fine when there are only one shared entity and multiple threads (1: N).

tit

N shareable entities-M threads

Now think of a situation when there is two washbasin inside a washroom and only one door. If we are using the previous approach, only p1 can use one washbasin at a time while p2 will wait outside. It is wastage of resource as no one is using B2 (washbasin).

A wiser approach would be to create a smaller room inside washroom and provide them one door per washbasin. In this way, P1 can access B1 and P2 can access B2 and vice-versa.

washbasin1;  
washbasin2;

Object lock1=new Object();
Object lock2=new Object();

  synchronized(lock1)
  {
    washbasin1;
  }

  synchronized(lock2)
  {
    washbasin2;
  }

tit

tit

Advantages of Lock over Synchronized(this)

  1. The use of synchronized methods or statements forces all lock acquisition and release to occur in a block-structured way.
  2. Lock implementations provide additional functionality over the use of synchronized methods and statements by providing

    1. A non-blocking attempt to acquire a lock (tryLock())
    2. An attempt to acquire the lock that can be interrupted (lockInterruptibly())
    3. An attempt to acquire the lock that can timeout (tryLock(long, TimeUnit)).
  3. A Lock class can also provide behavior and semantics that is quite different from that of the implicit monitor lock, such as

    1. guaranteed ordering
    2. non-re entrant usage
    3. Deadlock detection

Have a look at this SE question regarding various type of Locks:

Synchronization vs Lock

You can achieve thread safety by using advanced concurrency API instead of Synchronied blocks. This documentation page provides good programming constructs to achieve thread safety.

  • Lock Objects support locking idioms that simplify many concurrent applications.
  • Executors define a high-level API for launching and managing threads. Executor implementations provided by java.util.concurrent provide thread pool management suitable for large-scale applications.
  • Concurrent Collections make it easier to manage large collections of data, and can greatly reduce the need for synchronization.
  • Atomic Variables have features that minimize synchronization and help avoid memory consistency errors.
  • ThreadLocalRandom (in JDK 7) provides efficient generation of pseudorandom numbers from multiple threads.