Locks, Semaphores, CountDownLatch

Locks, Semaphores, CountDownLatch

In the Java programming language, the java.util.concurrent Thread Task Package Library provides Java developers with multiple synchronization utilities to easily manage communication and access control between multiple thread tasks.

Locks, Semaphores, CountDownLatch

The Java Thread Task Package Library contains three essential elements.

  • Locks (features) concept
  • Semaphore (features) concept
  • CountdownLatch (features) concept

These Java Thread Tasks solve multiple individual multithreading problems.

Locks with the java.util.concurrent class.

A lock is a synchronization mechanism in Java Thread Tasks that helps users control access to shared resources.

The lock concept ensures that when a user-defined thread task is executing a critical section, another thread task cannot use the same lock to enter the same protected section.

The Java Lock provides an interface for you.

java.util.concurrent.locks

And provides a commonly used implementation.

ReentrantLock

Example of a Java thread task lock.

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

class Tester {

private int test_value = 0;

private final Lock lock = new ReentrantLock();

void increment() {

lock.lock();

try {

test_value++;

} finally {

lock.unlock();

}

}

int gettest_value() {

return test_value;

}

}

Explaining the Java thread task lock.

In this example, the Java user first creates a lock.

private final Lock lock = new ReentrantLock();

Before accessing a shared resource in a Java thread task.

lock.lock();

The thread task automatically acquires a lock.

After completing a critical section in the thread task.

lock.unlock();

The lock is completely released.

The finally block statement is necessary because it ensures that the lock is automatically released even if a thread exception occurs.

synchronized vs Lock in java thread task

Both can provide mutual exclusion features in a Java thread task, but the Lock thread concept provides some additional control to the Java developer.

#Synchronized thread conceptLock concept in thread
1.Synchronized thread concept built into java programming languageLock concept interface used from concurrency libraries package
2.Synchronized thread automatically releases the monitor, when leaving the synchronized block/methodYou need to must explicitly call unlock() function or method for it
3.Synchronized thread concept simpler to use in java threadLock concept is more flexible to use with java thread task
4.Synchronized thread concept support no trylock() methodLock concept supports trylock() function method
5.Synchronized thread concept provide less controlLock concept provides us more control over lock acquisition

Example of a Java thread task lock.

The tryLock() function method in a Java expression allows a thread to attempt to acquire a lock without waiting too long.

if (lock.tryLock()) {

try {

// critical lock wait section

} finally {

lock.unlock();

}

}

Semaphore with java.util.concurrent class.

A semaphore in a Java thread controls access to a system data resource using a fixed number of permits.

Java users should think of this as a ticket with a limited number of values.

Semaphore Thread instance.

Semaphore semaphore = new Semaphore(4);

This means that initially, a maximum of 4 thread task permits are available.

Up to 4 thread tasks can acquire permits at the same time.

Semaphore Java Thread Task instance.

import java.util.concurrent.Semaphore;

class Resource {

private final Semaphore semaphore =

new Semaphore(3);

void useResource() {

try {

semaphore.acquire();

System.out.println(

Thread.currentThread().getName()

+ “this is using the thread task resource”

);

Thread.sleep(3000);

} catch (InterruptedException ex) {

Thread.currentThread().interrupt();

} finally {

semaphore.release();

}

}

}

Explaining the Semaphore in a Java Thread Task.

A Java developer creates a Semaphore in this condition.

Semaphore semaphore = new Semaphore(3);

Initially, there are three permits.

In which a thread requests a permit from the resource.

semaphore.acquire();

If a permit is available in the current task resource, the thread continues automatically.

If no permit is available in the thread resources, the thread waits in this condition.

In this, after the thread task has used the resource, it releases the permit.

semaphore.release();

Semaphore concept in a Java Thread Task.

Let’s assume that the Java Thread Task resource has three permits.

Semaphore thread task

|

+— Permit Request 1 → Thread Task P

|

+— Permit Request 2 → Thread Task Q

|

+— Permit Request 3 → Thread Task R

If in this example, Thread task S tries to acquire a permit, then

Thread S → acquire()

|

v

No permit available

|

WAIT for permit

When Thread P releases its permit,

Thread P → release()

|

v

Permit available

|

v

Thread S continues

Real-life example in a Java thread.

Imagine a company or organization with 4 fresh employee job vacancies available.

The number of fresh employee vacancies = 4.

Employee P → enters for a job.

Employee Q → enters for a job.

Employee R → enters for a job.

Employee S → waits in the thread’s task list.

When an employee leaves the company, a position becomes available for Employee S.

This concept is similar to how a semaphore works.

CountDownLatch with the java.util.concurrent class.

A CountDownLatch in a Java thread task helps one or more thread tasks wait until a fixed number of thread task operations have completed.

This process is initiated by a count.

CountDownLatch latch = new CountDownLatch(4);

In this case, each completed thread operation in the task decrements the count, using this concept.

latch.countDown();

In a Java program, a waiting thread calls the task.

latch.await();

When the thread count reaches zero, the waiting thread is allowed to continue.

CountDownLatch Java thread instance.

import java.util.concurrent.CountDownLatch;

public class Main {

public static void main(String[] args)

throws InterruptedException {

CountDownLatch latch =

new CountDownLatch(4);

Thread tsk1 = new Thread(() -> {

System.out.println(“Thread Task 1 done”);

latch.countDown();

});

Thread tsk2 = new Thread(() -> {

System.out.println(“Thread Task 2 done”);

latch.countDown();

});

Thread tsk3 = new Thread(() -> {

System.out.println(“Thread Task 3 done”);

latch.countDown();

});

Thread tsk4 = new Thread(() -> {

System.out.println(“Thread Task 4 done”);

latch.countDown();

});

tsk1.start();

tsk2.start();

tsk3.start();

tsk4.start();

latch.await();

System.out.println(

“All above thread tasks completed, Main thread continues.”

);

}

}

How this works in a Java program.

In this, at start.

Count = 4

When thread task 1 terminates.

countDown()

Count = 2

When thread task 2 terminates.

countDown()

Count = 1

When thread task 3 terminates.

countDown()

Count = 0

Now the other main thread, which was waiting on this task,

latch.await();

So this thread continues execution.

Essential feature of CountDownLatch in Java thread task.

A CountDownLatch in a Java thread task is typically a one-shot lock.

Once the thread count value reaches zero, it cannot be reset.

For a reusable thread synchronization barrier, Java provides a CyclicBarrier, which has a different purpose.

Difference Between Lock, Semaphore, and CountDownLatch in java thread task method

Each FeatureLock conceptSemaphore conceptCountDownLatch concept
What is purposelock Protect thread task shared resourceSemaphore Limit concurrent thread task resources accessCountDownLatch Wait for tasks/events to complete until next come
Controls provideIt provides Mutual exclusion features supportIt limits fixed Number of thread task permits in availabilityIt Completion available thread task to count
Which methodsIt used lock(), unlock() function or methodIt used acquire(), release() function or methodIt used await(), countDown()function or method to work
Multiple threads can proceed?This is Usually one per lock features supportedYes, it supports up to permit count value reach start to 0 valueIt Waiting threads task proceed when count reaches 0 numbers
Reusable? Or notYes, Lock thread taskYes, Semaphore thread taskCountDownLatch thread task No, normally one-shot
Where is General useIt Protect critical thread task sectionIt used to Connection/resource poolIt Wait for multiple thread tasks mechanism

A simple comparison between a Java thread task lock, semaphore, and CountDownLatch in real life.

Lock Java thread features.

For a lock Java user, imagine a bathroom with a single room.

1 Room Key → Only one individual user can use it at a time.

In this case, one thread acquires the lock, uses its resources, then releases them when needed. Then, accesses the lock = one by one.

Semaphore Java thread features.

For the Semaphore Java condition, a Java user should imagine a parking lot with 10 spaces.

10 bike permits → 10 bikes can enter.

As soon as the 11th bike enters this process, that bike must wait until a space becomes available in the existing parking lot.

Semaphore = A limited number of users can enter simultaneously.

CountDownLatch Java thread features.

For the CountDownLatch Java condition, a Java user should imagine waiting for 5 team member employees to arrive before starting a meeting.

Employee 1 arrives → count = 4

Employee 2 arrives → count = 3

Employee 3 arrives → count = 2

Employee 4 arrives → count = 1

Employee 5 arrives → count = 0

↓

Employee meeting begins

CountDownLatch = Waits until the required event/task is completed.

Easy way to remember locks, semaphores, and CountDownLatch in Java threads.

  • Lock → It protects the resources of a thread task.
  • Semaphore → It limits the number of users on a thread task.
  • CountDownLatch → It waits for the thread task to terminate.

Conclusion of Locks, Semaphores, CountDownLatch.

A lock is a synchronization mechanism or method used in Java to provide mutual exclusion and protect a critical section from simultaneous access by multiple threads. ReentrantLock is a commonly used implementation of the Lock interface.

A semaphore controls access to a task resource using a fixed number of permits in the Java thread concept. Threads acquire permits using the acquire() function and release them using the release() function. This feature is used when a limited number of task threads must simultaneously access an available thread resource.

A CountDownLatch is a synchronization aid in Java thread concept that allows one or more task threads to wait on a system resource until a fixed number of operations have completed. The count is decremented using the countDown() function method, and when the count reaches zero, the final waiting thread task is released.

One-line summary of Locks, Semaphores, and CountDownLatch.

  • Lock → Who can enter this Java thread task? It is managed.
  • Semaphore → How many numbers can enter this Java thread task? It is fixed.
  • CountDownLatch → When can I continue in this Java thread task? It is fixed and managed.

Leave a Reply