The Lock object in Java

Category: Java   Tags: Java, Java Thread, Java MultiThread, Thread Synchronization, Java Locks, Java Concurrent Collection

The Java package java.util.concurrent.locks has an interface Lock that support locks to control access to a shared resource. It is an alternative to using synchronized.

How a lock works?

In a multi thread environment when a thread try to access a shared resource, a lock that protect the resource is acquired. If another thread try to access the same resource it will be put on hold till the resource lock is not released by first thread. This way concurrent access to the resource is handled without any conflict.

One big advantage of Lock objects over the implicit locks is their ability to back out of an attempt to acquire a lock if it is not available immediately or within a specified period of time.

Methods

void lock()
Acquires the lock if available or waits until the lock is available.
void unlock()
Releases the lock.
boolean tryLock()
If lock is available, it will return immediately with the value true. If lock is not available, it will return immediately with the value false.

Here is one Java example that shows how a lock works using ReentrantLock.

JavaLockExample.java

                            package com.tutorial.javabasic;

                            import java.util.concurrent.locks.ReentrantLock;

                            class LockThread implements Runnable {

                                ReentrantLock lock;
                                String threadName;

                                LockThread(String name, ReentrantLock l) {
                                    lock = l;
                                    threadName = name;
                                }

                                @Override
                                public void run() {
                                    lock.lock();
                                    System.out.println(threadName + " has acquired the lock");
                                    for (int i = 1; i <= 5; i++) {
                                        System.out.println("Count: " + i);
                                        try {
                                            Thread.sleep(300);
                                        } catch (InterruptedException ex) {
                                        }
                                    }
                                    System.out.println(threadName + " has left the lock");
                                    lock.unlock();
                                }
                            }

                            class JavaLockExample {

                                public static void main(String s[]) {
                                    ReentrantLock lock = new ReentrantLock();
                                    Thread t1 = new Thread(new LockThread("ThreadA", lock));
                                    Thread t2 = new Thread(new LockThread("ThreadB", lock));
                                    t1.start();
                                    t2.start();
                                }
                            }
                        

Output:

                            ThreadA has acquired the lock
                            Count: 1
                            Count: 2
                            Count: 3
                            Count: 4
                            Count: 5
                            ThreadA has left the lock
                            ThreadB has acquired the lock
                            Count: 1
                            Count: 2
                            Count: 3
                            Count: 4
                            Count: 5
                            ThreadB has left the lock
                          

Here within the loop current thread is sleeping for 300 milliseconds. In this period other thread could have run the loop but as this is acquired by lock, no other thread will execute the loop until the current thread call unlock method.