important feature of java.util.concurrent package

 The java.util.concurrent package in Java provides a set of classes and interfaces that simplify the development of concurrent applications. This package addresses several issues that arise when multiple threads attempt to access shared resources. It includes utilities for thread management, synchronization, and concurrent data structures.

Here’s an overview of some key classes in the java.util.concurrent package, along with examples for each.

1. Executor Framework

The Executor framework provides a high-level mechanism for managing threads. The ExecutorService interface is the main interface in this framework, which allows for the creation and management of thread pools.

Example:

java
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ExecutorExample { public static void main(String[] args) { // Create a thread pool with a fixed number of threads ExecutorService executor = Executors.newFixedThreadPool(3); for (int i = 0; i < 5; i++) { final int taskId = i; executor.submit(() -> { System.out.println("Executing Task " + taskId + " in " + Thread.currentThread().getName()); }); } executor.shutdown(); } }

2. Future and Callable

The Callable interface is similar to Runnable, but it can return a result and throw a checked exception. The Future interface represents the result of an asynchronous computation.

Example:

java
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class CallableFutureExample { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(2); Callable<Integer> task = () -> { Thread.sleep(1000); return 123; }; Future<Integer> future = executor.submit(task); try { System.out.println("Result from Callable: " + future.get()); // Blocks until the result is available } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } finally { executor.shutdown(); } } }

3. CountDownLatch

CountDownLatch is a synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

Example:

java
import java.util.concurrent.CountDownLatch; public class CountDownLatchExample { public static void main(String[] args) throws InterruptedException { CountDownLatch latch = new CountDownLatch(3); for (int i = 0; i < 3; i++) { final int threadId = i; new Thread(() -> { System.out.println("Task " + threadId + " is completed"); latch.countDown(); // Decrease the count }).start(); } latch.await(); // Wait until count reaches 0 System.out.println("All tasks are completed"); } }

4. CyclicBarrier

CyclicBarrier is used to make a group of threads wait for each other to reach a common barrier point.

Example:

java
import java.util.concurrent.CyclicBarrier; public class CyclicBarrierExample { public static void main(String[] args) throws Exception { CyclicBarrier barrier = new CyclicBarrier(3, () -> System.out.println("All parties are arrived at the barrier, lets play!")); for (int i = 0; i < 3; i++) { final int threadId = i; new Thread(() -> { try { System.out.println("Thread " + threadId + " is doing something..."); Thread.sleep(1000); barrier.await(); // Wait until all parties arrive } catch (Exception e) { e.printStackTrace(); } }).start(); } } }

5. BlockingQueue

BlockingQueue is a type of queue that supports operations that wait for the queue to become non-empty when retrieving an element and wait for space to become available in the queue when storing an element.

Example:

java
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public class BlockingQueueExample { public static void main(String[] args) throws InterruptedException { BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10); // Producer new Thread(() -> { try { for (int i = 0; i < 10; i++) { queue.put(i); System.out.println("Produced: " + i); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }).start(); // Consumer new Thread(() -> { try { for (int i = 0; i < 10; i++) { int value = queue.take(); System.out.println("Consumed: " + value); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }).start(); } }

Conclusion

The java.util.concurrent package provides essential classes for developing concurrent applications, simplifying thread management and synchronization. By using the various tools provided by this package, developers can build more efficient and thread-safe applications. These examples illustrate only a fraction of the capabilities of this powerful package, and understanding its features is crucial for any Java developer working with multi-threaded applications.

Comments

Popular posts from this blog

Today Walkin 14th-Sept

Spring Elasticsearch Operations

Hibernate Search - Elasticsearch with JSON manipulation