Generate all the binary strings of N bits.

Generate all the binary strings of N bits. 


Given a positive integer number N. Generate all the binary strings(0 and 1) of N bits. 

Case 1
 Input: length=2
 Output:
 0 0
 0 1
 1 0
 1 1

Case 2
 Input: length=3
 Output:
 0 0 0
 0 0 1 
 0 1 0
 0 1 1
 1 0 0
 1 0 1
 1 1 0
 1 1 1

Case 3
 Input: length=1
 Output:
 0
 1

Algorithm:


We will see two approach of generating the binary string combination. 

First approach, where we will form the binary string one by one and once it matches the required length, we will backtrack and switch the binary digit. In this approach, as String is immutable each character we append to a String will create new String object.

Recursive stack trace of Generating all the binary strings of N bits.
generate all binary strings of length n with k bits set
Generate all the binary strings of N bits.

Second approach, In the first approach, each time we append the new character to String, a new String literal is created, so why to waste the space. In this approach we will use the fixed size array so that anytime we iterate and use the array we will always be working on fixed size array.

for more details on String and Memory management in Java, visit Java Memory Management Interview Questions

Java Program to Generate all the binary strings of N bits.


package javabypatel;
 
public class GenerateBinaryString {
 
    public void printBinaryCombination(int length, String str) {
        if (str.length() == length) {
            System.out.println(str);
            return;
        }
        printBinaryCombination(length, str + "0");
        printBinaryCombination(length, str + "1");
    }
 
    public static void main(String[] args) {
        GenerateBinaryString obj = new GenerateBinaryString();
        int length = 3;

        System.out.println("Approach 1");
        obj.printBinaryCombination(length, "");
    }
}

Optimized Approach: Using Array so no new String is created when a character is appended each time


package javabypatel;
 
import java.util.Arrays;
 
public class GenerateBinaryString {
 
    public void printBinaryCombination(int index, int[] arr) {
        if (index == arr.length) {
            System.out.println(Arrays.toString(arr));
            return;
        }
        arr[index] = 0;
        printBinaryCombination(index + 1, arr);
        arr[index] = 1;
        printBinaryCombination(index + 1, arr);
    }
 
    public static void main(String[] args) {
        GenerateBinaryString obj = new GenerateBinaryString();
        int length = 3;
 
        System.out.println("Approach 2");
        obj.printBinaryCombination(0, new int[length]);
    }
}

You may also like to see


Write a program to print all permutations of a given string without repetition. (Repetition of characters is not allowed).

Write a program to print all permutations of a given string with repetition. (Repetition of characters is allowed).

Print all subsets of a given set.

Enjoy !!!! 

If you find any issue in post or face any error while implementing, Please comment.

Check if an array is sorted in Java - Iterative and Recursive approach

Check if an array is sorted in Java - Iterative and Recursive approach.


Given an array, check if it is already sorted or not using both Iterative and Recursive way.

Lets see sample input and output for better understanding:
Check whether the array is sorted in Java
Check whether array is sorted or not

Reverse a Number in Java.

Reverse a Number in Java.


Given a integer number, reverse it.

Lets see sample input and output for better understanding:
Reverse a number in Java input output example
Reverse a number in Java input output example

Find length of the longest valid parenthesis substring

Find length of the longest balanced parenthesis in a string.


Given a string consisting of opening and closing parenthesis, find the length of the longest balanced parenthesis in it.

Lets see sample input and output for better understanding:
count longest valid parentheses length
longest valid parentheses count

Sort a Stack using Merge Sort

Sort a Stack using Merge Sort.


Lets see how to sort a stack using merge sort which uses divide and conquer recursive algorithm.

I recommend reading Merge sort first before proceeding.
Also, check Merge sort article on linked list that will help in understanding Merge sort and this article better.

Lets see sample input and output for better understanding:
sort a stack using recursion in java
Sort a Stack using Merge Sort in Java

Print path from root to a given node in a binary tree

Print path from root to a given node in a binary tree.


Given a Binary tree and a Key, Print a path from root to a key node.
Note: Given tree is Binary Tree and not Binary Search Tree.

Lets see sample input and output for better understanding:
Print path from root to given node in binary tree
Print path from root to given node in binary tree

Simple Deadlock Program in Java

Simple java program to create Deadlock.


Deadlock describes a situation where two or more threads are blocked forever, waiting for each other.


Let's consider an example, in the office we have shared Printer and Scanner where Employees has ability to do scanning and printing.

1. John has bunch of documents that it wants to Print first and also want to take a Scan later.
(Print and Scan)

2. Michael has bunch of documents that it wants to Scan first and also want to take a Print later.
(Scan and Print)

Difference between process and thread

Difference between process and thread.


Point 1:
A process is an executing instance of an application.
Thread is independent path of execution within a process. Process can have multiple threads,

Point 2:
Threads itself is capable enough to do all the things a process does and thread is a part of process that is why thread can be termed as light-weight process.

Point 3:
Since all the Threads are part of a same Process they all share same memory allocated by Process.
Process use memory allocated by OS.

Point 4:
Inter-thread communication between threads is easy whereas Inter-process communication is difficult.

Point 5:
Processes have independent data and code segments.
Thread shares the data segment, code segment, files etc. with its peer threads.

Point 6:
Process switching is complex as compared to thread switching because of the amount of variables need to be maintained in both of the case.

Per process items Per thread items
Address space  Program counter
Global variables Registers
Open files Stack
Child processes State
Pending alarms
Signals and signal handlers
Accounting information

Delete Middle Node of Linked List in Java

Delete Middle Node of Linked List in Java.


Given a linked list, Delete the middle node of linked list.

Lets see sample input and output for better understanding:

Remove duplicates from an unsorted linked list in Java.

Remove duplicates from an unsorted linked list in Java..


Given an unsorted linked list, Remove duplicates from it.

Lets see sample input and output for better understanding:

Check linked list is palindrome or not in java

Check linked list is palindrome or not in Java.


A palindromic number is a number that is the same when written forwards or backwards.

Lets see sample input and output for better understanding:

Find Running Median from a Stream of Integers

Find Running Median from a Stream of Integers in Java.


Given that integers are read from a data stream. Find median from the elements read so far in efficient way.

Lets see sample input and output for better understanding:

Find Moving Average of Last N numbers in a Stream.

Find Moving Average of Last N numbers in a Stream.


You are given a stream of numbers, calculate moving average of last N numbers in a stream.

In other words,
Given a stream of integers and a window size, calculate the moving average of all integers in the sliding window.

Lets see sample input and output for better understanding:

Search element In Sorted Rotated Array in Java

Search the element In Sorted Rotated Array in Java.


Given an array which is sorted in ascending order and is rotated, say for example
Example: original array [1,2,3,4,5,6,7] might become [3,4,5,6,7,1,2]
You are given a key to search. If key is found in the array return its index, otherwise return -1.

Note: You may assume no duplicate exists in the array, find an element in the rotated array in
O(log n) time.

Lets see sample input and output:

Find first non repeated character in a string in Java.

Find first non repeated character in a string in Java.


Given a string, find the first non-repeating character in it.

Lets see sample input and output:

Find largest number in Binary Search Tree which is less than or equal to N

Largest number in Binary Search Tree which is less than or equal to N.


We have a binary search tree and a number N. Our goal is to find the greatest number in the binary search tree that is less than or equal to N. Print -1 if the the value of the element doesn't exists.

We have to find the largest number inside the binary search tree that is smaller than or equal to the target number N.

Lets see sample input and output:

Check if a Binary Tree is a Mirror Image or Symmetric in Java.

Check if a Binary Tree is a Mirror Image or Symmetric..


Check if a given binary tree is a symmetric or you can also say check whether tree is a mirror of itself (ie, symmetric around its center)

Lets see sample input and output:

Find Container with Most Water in Java

Find Container with Most Water.


Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

Note: You cannot slant the container.

Lets understand what is the input and the expected output.

Find Power of a Number using Recursion in Java

Find Power of a Number using Recursion in Java.


Given two integers base and number, write a function to compute base^number. 
Assume that base and number are small and will not cause integer overflow.

Lets understand what is the input and the expected output.

Find length of longest substring without repeating characters in Java

Length of the longest substring without repeating characters in Java.


Given a string, find the length of the longest unique substring.

Lets understand what is the input and the expected output.

Maximum consecutive one’s in a binary array

Find the maximum consecutive 1's in an array of 0's and 1's. And Find length of the longest consecutive One's in binary representation.


Given a binary array, find the maximum number of consecutive 1s in this array or find the maximum consecutive 1's in an array of 0's and 1's.

Lets understand what is the input and the expected output.

Find sum of digits of a number until sum becomes single digit

Find sum of digits of a number until sum becomes single digit.


Given a non-negative integer, repeatedly add all its digits until the result has only one digit.
Lets understand what is the input and the expected output.


Hamming distance between two Integers in Java.

Hamming distance between two Integers in Java.


Given two integers, find the hamming distance between them. 

Hamming Distance: hamming distance is the count of bits that are different at same position in a binary representation of two numbers.

Lets understand what is the input and the expected output.

Check if a binary tree is subtree of another binary tree

Check if a binary tree is subtree of another binary tree.


Given two binary trees, check if the first tree is subtree of the second one. 
A tree is called subtree if all the nodes and its child of the subtree(S) is present in Tree(T) in the same structure.

Lets understand what is the input and the expected output.


Find element in a sorted array whose frequency is greater than or equal to n/2.

Find Majority Element in a Sorted Array in Java? OR Find element in a sorted array whose frequency is greater than or equal to n/2.


Given a sorted array, find the number in array that appears more than or equal to n/2 times.
Condition: there will always be element which is repeated more than n/2 times.

Lets understand with the help of example below,

Try to solve the problem in less than O(1) complexity.

Algorithm

If the element is sorted and such element is always present which is repeated more than n/2 times in that case the repeated element must be the middle element of the array.

If the most repeated element is starting from 0th index, in that case it has to stretch till middle index then only it will be repeated n/2 times,

If the most repeated element is present at last index, if that is the case than middle index should also contain the same element than only it would have be repeated n/2 times,

If the most repeated starts some where in the middle in this case it is sure it would be passing from the middle index for having its count greater than or equal to n/2 times.


package com.javabypatel.arrays;

public class MajorityOfElementInSortedArray {

    public static void main(String args[]) {
        int arr[] = { 1, 2, 3, 3 };
        int n = arr.length;
        System.out.println(findMajorityElement(arr, n));
    }
    public static int findMajorityElement(int arr[], int n) {
        return arr[n / 2];
    }
}

You may also like to see


Advanced Java Multithreading Interview Questions & Answers

Type Casting Interview Questions and Answers In Java?

Exception Handling Interview Question-Answer

Method Overloading - Method Hiding Interview Question-Answer

How is ambiguous overloaded method call resolved in java?

Method Overriding rules in Java

Interface interview questions and answers in Java


Enjoy !!!! 

If you find any issue in post or face any error while implementing, Please comment.

Check Majority Element in a Sorted Array in Java.

Majority Element in a Sorted Array in Java?


Given a sorted array, we need to find if a given x is a majority element.

What is Majority element: Number occurring more than half the size of the array is called Majority element.

Lets understand with the help of example below,
Try to solve the problem in less than O(N) complexity.

Algorithm


We will see two solutions one having time complexity O(N) and one using Binary Search approach having time complexity O(log N).

As the array is sorted we can use binary search to find the index of first occurrence of element to search and once that is found, we can directly add n/2 in that index to see if that index also contains the same element as element to search and if yes, then we have majority element else not.
package com.javabypatel.arrays;

public class MajorityOfElementInSortedArray {
    public static void main(String[] args) {

        int arr[];

        //arr = new int[] {1, 2, 2, 2, 3, 3, 3};
        //arr = new int[] {1, 1, 1, 2, 2, 3};
        //arr = new int[] {1, 1, 1, 2, 2, 2, 2};
        //arr = new int[] {2, 2};
        arr = new int[] {2};

        int x = 3;
        boolean result = isMajority(x, arr, arr.length);
        System.out.println(result);

        result = isMajorityUsingBinarySearch(x, arr, arr.length);
        System.out.println(result);
    }

    //Time complexity O(N)
    private static boolean isMajority(int elementToSearch, int[] arr, int length) {

        //Here we are calculating till what index we need to search for element.
        //we need to only search till length/2 index for even length array and length/2+1 for odd length array after that index if element is present/absent
        //doesn't matter as count of the element would not be greater than length/2+1 after crossing middle element.
        int searchUptil = length % 2 == 0 ? length / 2 : length / 2 + 1;

        for (int i = 0; i < searchUptil; i++) {

            //If we get the index of the first match elementToSearch then check the value at the (currentIndex + length/2)
            //if the value at that index is elementToSearch then elementToSearch occur more than length/2 times.
            if(arr[i] == elementToSearch && arr[i + arr.length/2] == elementToSearch) {
                return true;
            }
        }

        return false;
    }

    private static boolean isMajorityUsingBinarySearch(int elementToSearch, int[] arr, int length) {
        return isMajorityHelper(elementToSearch, arr, 0, length-1);

    }

    /*
        In this approach we will find the first instance of the elementToSearch using BinarySearch after that
        we will directly check the index n/2 from that point and if it is same as elementToSearch then we have
        n/2 count of elementToSearch else not.
     */
    static boolean isMajorityHelper(int elementToSearch, int[] arr, int start, int end) {
        if (start > end) {
            return false;
        }

        int mid = start + (end - start) / 2;

        if (arr[mid] == elementToSearch && (mid == 0 || arr[mid-1] < elementToSearch)) {

            //If we get the index of the first match elementToSearch then check the value at the (currentIndex + length/2)
            //if the value at that index is elementToSearch then elementToSearch occur more than length/2 times.
            if((mid + arr.length/2 < arr.length) && arr[mid + arr.length/2] == elementToSearch) {
                return true;
            }

            return false;

        } else if (arr[mid] < elementToSearch) {
            //Search on right side of mid.
            return isMajorityHelper(elementToSearch, arr, mid + 1, end);
        } else {
            //if the elementToSearch is found and is not the first instance or
            //if elementToSearch is greater than mid, continue searching on left side of mid.
            return isMajorityHelper(elementToSearch, arr, start, mid - 1);
        }
    }


}

You may also like to see


Advanced Java Multithreading Interview Questions & Answers

Type Casting Interview Questions and Answers In Java?

Exception Handling Interview Question-Answer

Method Overloading - Method Hiding Interview Question-Answer

How is ambiguous overloaded method call resolved in java?

Method Overriding rules in Java

Interface interview questions and answers in Java


Enjoy !!!! 

If you find any issue in post or face any error while implementing, Please comment.

Difference between CountDownLatch and CyclicBarrier in Java

Difference between CountDownLatch and CyclicBarrier in Java?


Difference 1:

In CountDownLatch, main thread which mostly invokes latch.await() waits for other threads to call countDown() and count reaches 0. In CyclicBarrier, threads wait for each other to complete their execution and reach at common point after which barrier is opened.


Note in CountDownLatch, it is not necessary same thread calls latch.countDown() 10 times or 10 threads calling latch.countDown and making the counter 0 but in case of CyclicBarrier different threads should reach at the common barrier point.

Let's see example of CyclicBarrier

package com.javabypatel.practice;

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierExample {
    
    public static void main(String args[]) {
        final CyclicBarrier cb = new CyclicBarrier(3, new Runnable(){
            @Override
            public void run(){
                System.out.println("Start the Game");
            }
        });

        Thread player1 = new Thread(new Player(cb), "Thread1");
        Thread player2 = new Thread(new Player(cb), "Thread2");
        Thread player3 = new Thread(new Player(cb), "Thread3");

        player1.start();
        player2.start();
        player3.start();
    }
}

class Player implements Runnable {

    private CyclicBarrier barrier;
    public Player(CyclicBarrier barrier) {
        this.barrier = barrier;
    }

    @Override
    public void run() {
        try {
            System.out.println(Thread.currentThread().getName() + " is waiting on barrier");
            barrier.await();
            System.out.println(Thread.currentThread().getName() + " has passed the barrier");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

Output:
Thread1 is waiting on barrier
Thread2 is waiting on barrier
Thread3 is waiting on barrier
Start the Game
Thread3 has passed the barrier
Thread2 has passed the barrier
Thread1 has passed the barrier

Difference 2:

CountDownLatch can not be reused once count reaches 0. CyclicBarrier can be reinitialized once parties reaches 0.

Difference 3:

CountDownLatch calls countDown() method to reduce the counter where as CyclicBarrier calls await() method to reduce the counter. Note, await() method blocks the thread from further execution until all thread reaches to a common barrier, countDown() method doesn't block anything.

Difference 4:

CountDownLatch can not trigger common event when count reaches 0, that is when count reaches 0, it just unblocks the blocked thread and proceed with executing further instructions.

CyclicBarrier can trigger common event (Runnable) once it reaches to a barrier point.
Example: refer above

Difference 5:

CyclicBarrier is used for map-reduce kind of operations, like say we want to count population on India, so we will create say 4 threads which counts the population of East, West, North and South.

Each thread will count the population of its Region, we also need to merge the result when data from all threads is ready until which merging cannot be done.

We can create a CyclicBarrier and block the thread after it finds the count, so all threads are blocked after counting the population of its respective region, once all thread reaches barrier, it is broken and merger(Runnable event) can be executed to count the population.

CountDownLatch is used when we want all thread to reach at common event but doesn't necessarily want to block them at that point and they can proceed after signaling(latch.countDown()), Say for example, if we want to start the client file poller after database service(thread1) and ConnectionPoolService with 100 threads(thread2) is up, so we can wait for thread1 and thread2 to call countDown() after which blocked main thread can proceed with starting client file pooler.


You may also like to see


Advanced Java Multithreading Interview Questions & Answers

Type Casting Interview Questions and Answers In Java?

Exception Handling Interview Question-Answer

Method Overloading - Method Hiding Interview Question-Answer

How is ambiguous overloaded method call resolved in java?

Method Overriding rules in Java

Interface interview questions and answers in Java


Enjoy !!!! 

If you find any issue in post or face any error while implementing, Please comment.

Difference between Join and CountDownLatch in Java

Difference between Join and CountDownLatch?



Difference 1:

Thread join method waits for other thread to finish before further executing current thread.
If t1.join is called in main thread, then main thread will wait at that point until t1 finishes its job.

CountDownLatch on the other end wait for its counter to reach 0 before executing current thread.
ExecutorService service = Executors.newFixedThreadPool(5);
final CountDownLatch latch = new CountDownLatch(3);

for(int i = 0; i < 5; i++) {
    service.submit(new Runnable() {
        public void run() {
            latch.countDown();
        }
    });
}

latch.await();

When latch.countDown is called, associated counter will be decremented and as soon as it reaches 0, main thread which was blocked at line latch.await() proceeds further.


Note:
Thread join method wait for joined thread to finish the execution before the main thread on which join method is called to starts its execution. Whereas in CountDownLatch, latch.await doesn't wait for the thread that calls latch.countDown() to be finished, it proceeds once the counter value reaches 0 and it has no association with the state of the thread that calls countDown().

Difference 2:

We can call join method when we have control over the threads but while using ExecutorService we don't have control over individual threads instead we deal with just submitting the task to framework and it internally manages threads in this situation using CountDownLatch is right approach.

Example above in difference 1 can be used as Reference.


Usage:

Example 1:
CountDownLatch is useful in Multiplayer games, Lets say we have a online chess game that can only be played when two player joins, in this case we will initialize the CountDownLatch to 2 and starts the game only after 2 threads(player) joins(calls countDown()).

Example 2:
Lets say we have some Timer task that we want to start only after all the modules of the application get loaded or when all the services is up.
 

You may also like to see


Advanced Java Multithreading Interview Questions & Answers

Type Casting Interview Questions and Answers In Java?

Exception Handling Interview Question-Answer

Method Overloading - Method Hiding Interview Question-Answer

How is ambiguous overloaded method call resolved in java?

Method Overriding rules in Java

Interface interview questions and answers in Java


Enjoy !!!! 

If you find any issue in post or face any error while implementing, Please comment.

ReentrantLock interview questions in Java

ReentrantLock interview questions in Java


Reentrant lock is more feature rich than using synchronized method/block.

This post assume you have basic idea about Threads and synchronization in Java, If not I recommend going through below Multithreading articles first,
When using synchronized method or a synchronized block, process of lock acquisition and release is actually handled internally but with Reentrant Lock, programmer has full control over thread locks and thread locking management is on developer by explicitly calling lock and unlock method, so there is both advantages and disadvantages of this Reentrantlock.
reentrantlock interview questions in java
Reentrantlock interview questions in java

Question 1: What is the difference between ReentrantLock and Synchronized keyword in Java?


Time to wait for getting a Lock:

When a thread invoke synchronized method or a block, It has to first acquire a lock and then only it can proceed, there is no control to programmer over a time a thread should keep waiting for lock. 

Lets understand above point with an example, When thread 1 tries to call any synchronized method or synchronized block, It has to wait until some other thread say thread 2 release the lock on the same monitor. What if the thread 2 doesn't release the monitor due to some reason, How much time thread 1 has to wait, there is no control to the programmer till when Thread 1 will be waiting.

Using ReentrantLock which was introduced in jdk 1.5 under java.util.concurrent.locks package, We can provide a timeout till when thread should keep waiting for acquiring a lock and after that time thread will proceed with normal execution. this will give more control to threads while waiting for a lock instead of indefinitely waiting or getting blocked till lock is acquired.

Example: tryLock method,
  
Lock lock = new ReentrantLock();
lock.tryLock(long timeout, TimeUnit unit)
Complete trylock example in Java
package javabypatel;

import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadSafeArrayList<E> {
    public static void main(String[] args) throws Exception {
        final ReentrantLock lock1 = new ReentrantLock();
        final ReentrantLock lock2 = new ReentrantLock();

        String printerLock = "PrinterLock";
        String scannerLock = "ScannerLock";

        Runnable try1_2 = getRunnable(lock1, printerLock, lock2, scannerLock);
        Runnable try2_1 = getRunnable(lock2, scannerLock, lock1, printerLock);
        Thread t1 = new Thread(try1_2);
        t1.start();
        Thread t2 = new Thread(try2_1);
        t2.start();
    }

    private static Runnable getRunnable(final ReentrantLock lock1, final String lock1Name,
        final ReentrantLock lock2, final String lock2Name) {
        return new Runnable() {
            @Override
            public void run() {
                try {
                    if (lock1.tryLock(5, TimeUnit.SECONDS)) {
                        System.out.println(lock1Name + " acquired by thread " + Thread.currentThread());

                        Random rand = new Random();

                        if (lock2.tryLock(rand.nextInt(10), TimeUnit.SECONDS)) {
                            System.out.println(lock2Name + " acquired by thread " + Thread.currentThread());
                            Thread.sleep(2000);
                        } else {
                            System.out.println("Could not acquire " + lock2Name + " by thread " + Thread.currentThread());
                            lock1.unlock();
                            System.out.println(lock1Name + " released by thread " + Thread.currentThread());
                        }
                    } else {
                        System.out.println("Unable to acquire " + lock1Name + " by thread " + Thread.currentThread());
                    }
                } catch (InterruptedException e) {
                    System.out.println("I am interrupted" + Thread.currentThread());
                } finally {
                    if (lock1.isHeldByCurrentThread())
                        lock1.unlock();
                    if (lock2.isHeldByCurrentThread())
                        lock2.unlock();
                }
            }
        };
    }
}
Fairness policy:

When thread (say thread 1) calls synchronized method or synchronized block, it has to first acquire the monitor and then only can enter inside synchronized area. If monitor is acquired by other thread say thread 2 then thread 1 has to wait. 

Also, there can be many threads(say thread 1, thread 5, thread 8 etc) waiting for the same monitor. what will happen when thread 2 release the lock on monitor, which thread will be the next to execute among thread 1, thread 5, thread 8 waiting for lock? 

There is no guarantee which thread will get the control and that totally depends on scheduler, this leads to problem of thread (say thread 1) not getting monitor even though it is waiting for longest time among other threads for acquiring the lock and other thread (say thread 5) gets the monitor even if it just joined the waiting queue. ReentrantLock solves this problem by adding fairness policy while creating 
ReentrantLock  object.

While creating a ReentrantLock object, we can provide fairness property for making the lock fair. Fairness property provides lock to longest waiting thread, in case of contention. With fairness enabled, Threads get the lock in the order they requested it.

Example:
  
  ReentrantLock lock = new ReentrantLock(true);

Note: Performance is degraded by fairness policy.

LockInterruptibly

When thread 1 calls the synchronized method or synchronized block, it will be blocked until lock on the monitor is available. programmer don't have control to resume the blocked thread.
ReentrantLock provides a method called lockInterruptibly(), which can be used to interrupt the thread when it is waiting for lock. so that it can no longer in blocked state indefinitely.

void lockInterruptibly()
If thread is able to acquire lock then this method increments lock hold count by 1.
If the lock is with another thread then the current thread waits until it gets the lock or some other thread interrupts the thread.

lockinterruptibly example in java:
public class LockInterruptiblyExample{
 final ReentrantLock reentrantLock = new ReentrantLock();
 
 public void performTask() {
      try {
       reentrantLock.lockInterruptibly(); //wait till thread get the lock or till other thread interrupts
         //and you can control further execution from catch block
       try {
         //.....
       } finally {
      reentrantLock.unlock();
       }
      } catch (InterruptedException e) {
       e.printStackTrace();
      }
 }
} 


Number of Threads blocked on monitor:

Using synchronized method or block doesn't provide any mechanism to know how many threads are blocked to acquire a lock on monitor
Reentrant lock provides getQueueLength() method which return number of threads that may be waiting to acquire this lock in java.


Lock Unlock in different scope

With Synchronized keyword, lock need to be acquired and released at complete method level or at block level. Lets say when thread t1 tries to acquire multiple locks by calling multiple synchronized method, in that case multiple locks are acquired by t1 and they must all be released in the opposite order.

In ReentrantLock, locks can be acquired and released in different scopes, and allowing multiple locks to be acquired and released in any order.

Example:

ReentrantLock reentrantLock;

public void getA() {
  reentrantLock.lock();
}

public void getB() {
  reentrantLock.unlock();
}


More than one waiting condition

When lock is acquired using intrinsic lock by calling synchronized method/block, this threads then communicate using wait(), notify() and notifyAll() methods of Object class.

Condition allows inter thread communication when lock is acquired using extrinsic way by Lock interface. Condition defines methods such as await(), signal() and signalAll() for waiting and notifying.

Using synchronized block/method for a common monitor, there is no way to distinguish for what reason each thread is waiting, thread t1, t2, t3 might be blocked say for putting the data in the queue, other threads say t5, t6, t7, t8 might be waiting for reading data from the queue and they all are waiting on common monitor "queue".

Lets consider producer consumer situation, say we have a queue of size one and is full and t1, t2, t3 is blocked for putting the data in the queue, so they are in waiting state.
Now, t5, t6, t7, t8 tries to read data from the queue, lets say t5 would be reading the data in the queue, meanwhile t6, t7, t8 would be in waiting state.

After t5 read the data from the queue, it calls notifyAll, this call is to notify producers(t1,t2,t3) to put the data in the queue as there is a space now,
there are total 6 threads waiting for monitor "queue"
putting data in queue = t1, t2, t3,
reading data from queue = t4, t6, t7
currently monitor is held by executing thread = t5

when t5 calls notifyAll, there is no guarantee who is going to be wake up, might be thread t7 wake up and it has to go back to waiting state again as nothing is there to read, next time might be t4 gets a chance and again no use of t4 wakeup and it will go back to waiting state.
When someone from t1, t2 or t3 wakes up then only things would proceed.

If there is a way for t5 thread to notifyAll only to threads that want to put data to queue t1, t2 and t3 then it would be helpful. Using Condition that is possible.

With intrinsic lock using synchronized method/block there is no way to group the waiting threads waiting on a common monitor. with Condition, we can create multiple wait sets.

When you use Condition: await()/signal() you can distinguish which object or group of objects/threads get a specific signal.

Using Condition, we now have way to create more than one condition variable per monitor.
Monitors that use the synchronized keyword can only have one. This means Reentrant locks(implementation of Lock interface) support more than one wait()/notify() queue.

    private final Lock lock = new ReentrantLock();
    private final Condition queueEmpty = lock.newCondition();
    private final Condition queueFull = lock.newCondition();

    public void putData(int data) {
        lock.lock();
        try {
            while (queue is empty) {
                queueEmpty.await();
            }
            this.data = data;
            queueFull.signalAll();
                      
        } finally {
            lock.unlock();
        }
    }

    public void getData() {
        lock.lock();
        try {
            while (queue is full) {
                queueFull.await();
            }
            queueEmpty.signalAll();
        } finally {
            lock.unlock();
        }
    }


Now with queueFull.signalAll(), only threads those are waiting for this condition on same monitor "lock" will be awaked and rest will still be waiting.

Condition interface also comes with useful method that is:
boolean awaitUntil(Date deadline): Causes the current thread to wait until it is signaled or interrupted, or the specified deadline elapses.

Note: there is similar method wait(long timeInMilliseconds), but when there is System date change, above method will have impact while wait will keep waiting for provided timeInMilliseconds. So decide which is better in your situation.

Question 2. Does synchronized method and block are reentrant?

Yes. synchronized method, synchronized block and Reentrant lock are all reentrant in nature.

What is the meaning of Reentrant?
A reentrant lock is one where a process can claim the lock multiple times without blocking on itself.
In simple terms, ability to call the same synchronized method again and again without getting blocked is called reentrant.

Lets understand with example,
synchronized  void getA () {
    getB();
}

synchronized void getB () {
    getA();
}

What will happen if say Thread 1 calls obj.getA(), thread 1 will  acquire a lock on obj and call method getA(). inside which it calls getB()(which is obj.getB()), thread 1 already hold the lock on obj so it will call getB(), 
getB() call getA()(which is obj.getA()), thread 1 already hold a lock on obj so it is allowed to call the method getA() again. this is called Reentrant. same lock is claimed multiple times that is each time getA is called.


Question 3. Show simple example on how to write lock and unlock method of Reentrant Lock? 
public void getA() { 
      reentrantLock.lock(); 
      try{ 
          //...
      } catch(Exception e) { 
          e.printStackTrace(); 
      } finally { 
          reentrantLock.unlock(); 
      }     
} 




Question 4. Why ReentrantLock is called ReentrantLock?

ReentrantLock keep track of lock acquisition count associated with the lock.
when a call reentrantLock.lock() is made to acquire a lock and if the lock is obtained then the acquisition count variable is incremented to 1, stating that lock has been acquired one time till now.

Similarly, when a call reentrantLock.unlock() is made acquisition count variable is decremented by 1.
When the count reaches 0 then only other thread will be allowed to take the lock.

When a thread t1 acquires a reentrant lock inside method say getA() and make a call to another method say getB() from inside getA() which is also guarded by reentrant lock, in this case thread t1 will acquire a lock twice one for getA() method and one for getB() method. In this case, if a thread t1 that is already holding a lock is now acquiring it again inside getB(), the acquisition count is incremented to 2 and now the lock needs to be released twice to fully release the lock.

Let's see sample program,

package com.javabypatel.concurrency;

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockExample {
    public static void main(String[] args) {
        ReentrantLock reentrantLock = new ReentrantLock();

        Thread t1 = new Thread(new Printer("Thread1", reentrantLock));
        Thread t2 = new Thread(new Printer("Thread2", reentrantLock));

        t1.start();
        t2.start();
    }
}

class Printer implements Runnable {

    private String threadName;
    private ReentrantLock reentrantLock;

    Printer(String threadName, ReentrantLock reentrantLock) {
        this.threadName = threadName;
        this.reentrantLock = reentrantLock;
    }

    @Override
    public void run() {
        System.out.println("Thread " + threadName + " is waiting to get lock");
        reentrantLock.lock();
        try {
            System.out.println("Thread " + threadName + " acquired lock");
            getA();
        } finally {
            reentrantLock.unlock();
            System.out.println("Thread " + threadName + " released the lock and the lock held count is :"+reentrantLock.getHoldCount());
        }
    }

    public void getA() {
        System.out.println("getA :: Thread " + threadName + " is waiting to get lock");
        try {
            reentrantLock.lock();
            System.out.println("getA :: Thread " + threadName + " acquired lock");
            System.out.println("getA :: Lock count held by thread " + threadName + " : " + reentrantLock.getHoldCount());

        } finally {
            reentrantLock.unlock();
            System.out.println("getA :: Thread " + threadName + " released the lock and the lock held count is :"+reentrantLock.getHoldCount());
        }
    }
}


Output:

Thread Thread1 is waiting to get lock
Thread Thread1 acquired lock
getA :: Thread Thread1 is waiting to get lock
getA :: Thread Thread1 acquired lock
getA :: Lock count held by thread Thread1 : 2
getA :: Thread Thread1 released the lock and the lock held count is :1
Thread Thread1 released the lock and the lock held count is :0
Thread Thread2 is waiting to get lock
Thread Thread2 acquired lock
getA :: Thread Thread2 is waiting to get lock
getA :: Thread Thread2 acquired lock
getA :: Lock count held by thread Thread2 : 2
getA :: Thread Thread2 released the lock and the lock held count is :1
Thread Thread2 released the lock and the lock held count is :0

You can see lock held count should go back to 0 for another thread to acquire a lock.


You may also like to see


Advanced Java Multithreading Interview Questions & Answers

Type Casting Interview Questions and Answers In Java?

Exception Handling Interview Question-Answer

Method Overloading - Method Hiding Interview Question-Answer

How is ambiguous overloaded method call resolved in java?

Method Overriding rules in Java

Interface interview questions and answers in Java

Enjoy !!!! 

If you find any issue in post or face any error while implementing, Please comment.

Delete all occurrences of a given key in a linked list.

Delete all occurrences of a given key in a linked list.


Given a Linked list and key to delete, Remove all the occurrences of a given key in singly linked list.

Lets understand what is the input and the expected output.

Find K largest elements in array using Min Heap.

Find K largest elements in array using Min Heap.


Given a unsorted array, Find k largest element in array.

Find K largest elements in array using Max Heap

Lets understand what is the input and the expected output.


Find K largest elements in array using Max Heap

Find K largest elements in array using Max Heap.


Given a unsorted array, Find k largest element in array.

Heap Sort Algorithm

Lets understand what is the input and the expected output.


Quick Sort in Java

Quick Sort in Java.


Given a unsorted array, Sort it using Quick Sort Algorithm.

Merge sort linked list java

Lets understand what is the input and the expected output.