Selasa, 01 Juli 2014

ReentrantLock Example in Java, Difference between synchronized vs ReentrantLock




ReentrantLock in Java is added on java.util.concurrent package in Java 1.5
along with other concurrent utilities like CountDownLatch, Executors and CyclicBarrier.
ReentrantLock is one of
the most useful addition in Java concurrency package and several of concurrent
collection classes from
java.util.concurrent package is written using ReentrantLock, including
ConcurrentHashMap, see How ConcurrentHashMap works in Java
fo
r more details. Two key feature of
ReentrantLock, which
provides more control on lock acquisition is trying to get a lock with ability to interrupt,
and a timeout on waiting for lock, these are key for writing responsive and
scalable systems in Java. In short,
ReentrantLock extends
functionality of synchronized keyword in Java
and
open path for more controlled locking in Java. 





In this Java concurrency tutorial we will learn :


  • What is ReentrantLock in Java ?

  • Difference between ReentrantLock and synchronized keyword
    in Java?

  • Benefits of using Reentrant lock in Java?

  • Drawbacks of using Reentrant lock in concurrent
    program?

  • Code Example of ReentrantLock in Java?








What is ReentrantLock in Java



On class level,  ReentrantLock is a
concrete implementation of Lock interface provided in Java concurrency package
from Java 1.5 onwards.  As per Javadoc,
ReentrantLock is mutual
exclusive lock, similar to implicit locking provided by synchronized keyword in Java, with extended feature like fairness, which can be used to provide lock
to longest waiting thread. Lock is acquired by
lock() method and
held by Thread until a call to
unlock() method. Fairness  parameter is provided while creating instance
of
ReentrantLock in constructor. ReentrantLock provides same
visibility and ordering guarantee, provided by implicitly locking, which means,
unlock() happens
before another thread get
lock().








Difference between ReentrantLock and synchronized
keyword in Java



Though ReentrantLock provides same visibility and orderings guaranteed as implicit lock, acquired by synchronized keyword in Java,
it provides more functionality and differ in certain aspect. As stated
earlier,  main difference between
synchronized and ReentrantLock
is ability to trying for lock interruptibly, and
with timeout. Thread doesn’t need to block infinitely, which was the case with
synchronized. Let’s see few more differences between synchronized and Lock in
Java.





1) Another significant difference between ReentrantLock and
synchronized keyword is fairness.
synchronized keyword
doesn't support fairness. Any thread can acquire lock once released, no preference can be specified, on the other hand you can make
ReentrantLock fair by
specifying
fairness property, while creating instance
of
ReentrantLock. Fairness property provides lock to longest waiting
thread, in case of contention.





2) Second difference between synchronized and Reentrant lock is tryLock() method. ReentrantLock
provides convenient
tryLock() method, which acquires lock only
if its available or not held by any other thread. This reduce blocking of
thread waiting for lock in Java application.





3) One more worth noting difference between ReentrantLock and
synchronized keyword in Java is, ability to interrupt Thread while
waiting for
Lock. In case of synchronized keyword, a
thread can be blocked waiting for lock, for an indefinite period of time and
there was no way to control that.
ReentrantLock provides a
method called
lockInterruptibly(), which can be used to interrupt
thread when it is waiting for lock. Similarly
tryLock() with
timeout can be used to timeout if lock is not available in certain time period.





4) ReentrantLock also provides convenient method to get List of all
threads waiting for lock.





So, you can see, lot of significant differences between synchronized keyword
and ReentrantLock in Java. In short, Lock interface adds lot of power and flexibility and allows some control over lock acquisition process, which can be
leveraged to write highly scalable systems in Java.


Benefits of ReentrantLock in Java




ReentrantLock in Java with example and difference between synchronized keyword

Most of the benefits derives from the differences covered between synchronized
vs ReentrantLock
in last section. Here is summary of benefits offered by ReentrantLock over synchronized in Java:





1) Ability to lock interruptibly.


2) Ability to timeout while waiting for lock.


3) Power to create fair lock.


4) API to get list of waiting thread for lock.


5) Flexibility to try for lock without blocking.





Disadvantages of ReentrantLock in Java



Major drawback of using ReentrantLock in Java is wrapping method body
inside try-finally block, which makes
code unreadable and hides business logic. It’s really cluttered and I hate it
most, though IDE like Eclipse and Netbeans can add those try catch block for you.
Another disadvantage is that, now programmer is responsible for acquiring and
releasing lock, which is a power but also opens gate for new subtle bugs, when
programmer forget to release the lock in finally block.





Lock and ReentrantLock Example in Java



Here is a complete code example of How to use Lock interface
and
ReentrantLock in Java. This program locks a method called getCount(),
which provides unique count to each caller. Here we will see both
synchronized and ReentrantLock version of same program. You can see code with synchronized
is more readable but it’s not as flexible as locking mechanism provided by
Lock interface.





import java.util.concurrent.locks.ReentrantLock;


import java.util.logging.Level;


import java.util.logging.Logger;





/**


 * Java program to show, how to use
ReentrantLock in Java.


 * Reentrant lock is an alternative way of
locking


 * apart from implicit locking provided by
synchronized keyword in Java.


 *


 * @author  Javin Paul


 */


public class ReentrantLockHowto {





    private final ReentrantLock lock = new ReentrantLock();


    private int count = 0;





     //Locking using Lock
and ReentrantLock


     public int getCount() {


        lock.lock();


        try {


            System.out.println(Thread.currentThread().getName() + " gets
Count: "
+ count);


            return count++;


        } finally {


            lock.unlock();


        }


     }





     //Implicit locking
using synchronized keyword


     public synchronized int getCountTwo() {


            return count++;


     }





    





    public static void main(String args[]) {


        final ThreadTest counter = new ThreadTest();


        Thread t1 = new Thread() {





            @Override


            public void run() {


                while (counter.getCount() < 6) {


                    try {


                        Thread.sleep(100);


                    } catch (InterruptedException ex) {


                        ex.printStackTrace();                    }


                }


            }


        };


      


        Thread t2 = new Thread() {





            @Override


            public void run() {


                while (counter.getCount() < 6) {


                    try {


                        Thread.sleep(100);


                    } catch (InterruptedException ex) {


                        ex.printStackTrace();


                    }


                }


            }


        };


      


        t1.start();


        t2.start();


      


    }


}





Output:


Thread-0 gets Count: 0


Thread-1 gets Count: 1


Thread-1 gets Count: 2


Thread-0 gets Count: 3


Thread-1 gets Count: 4


Thread-0 gets Count: 5


Thread-0 gets Count: 6


Thread-1 gets Count: 7





That’s all on What is ReentrantLock in Java, How to use with simple example, and difference
between
ReentrantLock and synchronized keyword in Java.
We have also seen significant enhancement provided by
Lock interface
over synchronized e.g. trying for lock, timeout while waiting for lock and
ability to interrupt thread while waiting for lock. Just be careful to release
lock in finally block.





Related Java multithreading and concurrency tutorials from
Javarevisited Blog





























Source:http://javarevisited.blogspot.com/2013/03/reentrantlock-example-in-java-synchronized-difference-vs-lock.html

Tidak ada komentar:

Posting Komentar