can anyone explain how to use Reentrant Lock in java over Synchronized with some best examples
Asked Answered
A

3

7

When I run the example class at http://javarevisited.blogspot.in/2013/03/reentrantlock-example-in-java-synchronized-difference-vs-lock.html, I'm seeing the same behavior as with synchronized.

Andante answered 28/8, 2013 at 18:22 Comment(0)
S
6

Here are three ways, methods, of a thread accessing a lock and one for letting go of the lock. You might want to try implementing these using the synchronized keyword. The extended capabilities and advantages of using ReentrantLock will become apparent.

public class DoorLockUsingLock {

    private int counter= 0;
    private Thread owner= null;
    private Lock l = new ReentrantLock();
    private Condition notLocked= l.newCondition();

    public void lockItDown() throws InterruptedException {
        l.lockInterruptibly();
        try {
            while ((counter> 0) && (owner!= Thread.currentThread())) {
                notLocked.await();
            }
            counter++;
            owner = Thread.currentThread();
        } finally {
            l.unlock();
        }
    }

    public void lockItDownUninterruptibly() {
        l.lock();
        try {
            while ((counter > 0) && (owner != Thread.currentThread())) {
                notLocked.awaitUninterruptibly();
            }
            counter++;
            owner= Thread.currentThread();
        } finally {
            l.unlock();
        }
    }

    public boolean tryLockItDown(long timeout, TimeUnit unit) throws InterruptedException {
        long time = unit.toNanos(timeout);
        long end = System.nanoTime() + time;
        boolean success = l.tryLock(timeout, unit);
        if (!success) {
            return false;
        }
        try {
            time = end- System.nanoTime();
            while ((counter> 0) && (owner != Thread.currentThread()) && (time > 0)) {
                notLocked.await(time, TimeUnit.NANOSECONDS);
                time = end - System.nanoTime();
            }
            if (time > 0) {
                counter++;
                owner = Thread.currentThread();
                return true;
            }
            return false;
        } finally {
            l.unlock();
        }
    }

    public void unlockIt() throws IllegalMonitorStateException {
        l.lock();
        try {
            if (counter== 0) {
                throw new IllegalMonitorStateException();
            }
            if (owner!= Thread.currentThread()) {
                throw new IllegalMonitorStateException();
            }
            counter--;
            if (counter == 0) {
                owner = null;
                notLocked.signal();
            }
        } finally {
            l.unlock();
        }
    }
}
Sanborn answered 28/8, 2013 at 18:47 Comment(2)
This basically reproduces synchronized, wait, and notify behavior. ReentrantLock and Condition cleaned up the semantics and allow for fairness, but are otherwise mostly the same.Mcdonough
@DavidEhrmann Fair queueing is just part of the story. ReentrantLock also allows for unconditional, polled, timed, or interruptible lock acquisition. It is not possible too exit intrinsic locks that are deadlocked short from restarting the JVM.Alnico
A
2

From the JavaDoc of the ReetrantLock class:

A reentrant mutual exclusion Lock with the same basic behavior and semantics as the implicit monitor lock accessed using synchronized methods and statements, but with extended capabilities.

In your example, you do not use the "extended capabilities"; you use the ReentrantLock as an equivalent alternative to the synchronized method (except that with the synchronized statement, you use this as the lock). So the two methods must behave the same.

Alithea answered 28/8, 2013 at 18:35 Comment(1)
This, and there's a ReentrantReadWriteLock that's can be useful. That would be annoying to implement with synchronized.Mcdonough
C
0

No, you generally won't see a difference in behavior. But as the website says, there are a couple cases you'll want to use a ReentrantLock instead of synchronized.

  1. You want waiting threads to be fairly selected.
  2. You want to use the tryLock() method.
  3. You want to interrupt a waiting thread and have it do something else.
  4. The performance of ReentrantLock is better than synchronized, and you care about that.

If you don't need any of those improvements, using synchronized is just fine, and you may not be able to tell the difference.

Carlist answered 28/8, 2013 at 18:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.