Information

Title

AtomicIntegre and CountDownLatch

Content

Advanced Examples Using AtomicInteger and CountDownLatch


Below are examples of how AtomicInteger and CountDownLatch can be used in more advanced scenarios:


1. AtomicInteger for a Multi-Threaded Counter with Custom Logic


AtomicInteger is often used to handle counters in a thread-safe manner. Here’s an example where it is used to count tasks completed by multiple threads and apply some custom logic.


Scenario: Count Tasks with Custom Increment Logic


import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.atomic.AtomicInteger;


public class AtomicIntegerExample {

    public static void main(String[] args) {

        AtomicInteger counter = new AtomicInteger(0);

        ExecutorService executor = Executors.newFixedThreadPool(5);


        Runnable task = () -> {

            int increment = (int) (Math.random() * 10); // Custom increment

            int updatedValue = counter.addAndGet(increment);

            System.out.println(Thread.currentThread().getName() + " incremented by " + increment + ", total: " + updatedValue);

        };


        // Submit 10 tasks

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

            executor.submit(task);

        }


        executor.shutdown();

    }

}


Key Points:

addAndGet(int delta) ensures atomic addition to the counter.

Each thread performs a custom increment without causing race conditions.


2. CountdownLatch for Coordinating Multiple Threads


CountDownLatch can be used to wait for a set of threads to complete tasks before proceeding.


Scenario: Waiting for Multiple Threads to Complete a Preprocessing Step


import java.util.concurrent.CountDownLatch;


public class CountDownLatchExample {

    public static void main(String[] args) throws InterruptedException {

        int numberOfTasks = 5;

        CountDownLatch latch = new CountDownLatch(numberOfTasks);


        Runnable worker = () -> {

            try {

                System.out.println(Thread.currentThread().getName() + " is processing...");

                Thread.sleep((long) (Math.random() * 3000)); // Simulate work

                System.out.println(Thread.currentThread().getName() + " finished processing.");

            catch (InterruptedException e) {

                Thread.currentThread().interrupt();

            finally {

                latch.countDown(); // Reduce the latch count

            }

        };


        // Start worker threads

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

            new Thread(worker).start();

        }


        System.out.println("Main thread is waiting for workers to finish...");

        latch.await(); // Wait until the latch count reaches zero

        System.out.println("All workers have finished. Main thread resumes.");

    }

}


Key Points:

latch.countDown() reduces the latch count by 1 each time a worker finishes.

latch.await() blocks the main thread until all workers finish their tasks.


3. Using AtomicInteger with CountdownLatch for Task Tracking


Combine AtomicInteger and CountDownLatch to track how many threads successfully completed a task.


Scenario: Track Successful Task Completions


import java.util.concurrent.CountDownLatch;

import java.util.concurrent.atomic.AtomicInteger;


public class AtomicIntegerWithLatchExample {

    public static void main(String[] args) throws InterruptedException {

        int numberOfThreads = 5;

        CountDownLatch latch = new CountDownLatch(numberOfThreads);

        AtomicInteger successCounter = new AtomicInteger(0);


        Runnable task = () -> {

            try {

                System.out.println(Thread.currentThread().getName() + " is working...");

                if (Math.random() > 0.3) { // Simulate a success with 70% probability

                    successCounter.incrementAndGet();

                }

                Thread.sleep((long) (Math.random() * 2000));

            catch (InterruptedException e) {

                Thread.currentThread().interrupt();

            finally {

                latch.countDown(); // Decrease latch count

            }

        };


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

            new Thread(task).start();

        }


        latch.await(); // Wait for all threads to finish

        System.out.println("All threads finished. Successful completions: " + successCounter.get());

    }

}


Key Points:

AtomicInteger is used to count successful completions in a thread-safe way.

CountDownLatch ensures the main thread waits for all tasks to complete.


4. Parallel Processing with CountDownLatch


CountDownLatch can be used to implement parallel processing where multiple tasks must start simultaneously.


Scenario: Launch All Threads Simultaneously


import java.util.concurrent.CountDownLatch;


public class ParallelProcessingExample {

    public static void main(String[] args) throws InterruptedException {

        int numberOfThreads = 5;

        CountDownLatch startLatch = new CountDownLatch(1); // Wait for the signal to start

        CountDownLatch finishLatch = new CountDownLatch(numberOfThreads); // Wait for all threads to finish


        Runnable task = () -> {

            try {

                startLatch.await(); // Wait for the signal

                System.out.println(Thread.currentThread().getName() + " started working...");

                Thread.sleep((long) (Math.random() * 3000)); // Simulate work

                System.out.println(Thread.currentThread().getName() + " finished.");

            catch (InterruptedException e) {

                Thread.currentThread().interrupt();

            finally {

                finishLatch.countDown(); // Signal completion

            }

        };


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

            new Thread(task).start();

        }


        System.out.println("Ready... Set...");

        startLatch.countDown(); // Signal all threads to start

        System.out.println("Go!");


        finishLatch.await(); // Wait for all threads to finish

        System.out.println("All threads have completed their work.");

    }

}


Key Points:

startLatch ensures all threads start simultaneously.

finishLatch ensures the main thread waits for all threads to complete.


5. Limiting Access with AtomicInteger


Use AtomicInteger to simulate a rate limiter where only a fixed number of threads are allowed to access a resource concurrently.


Scenario: Simulating a Rate Limiter


import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.atomic.AtomicInteger;


public class RateLimiterExample {

    public static void main(String[] args) {

        AtomicInteger activeThreads = new AtomicInteger(0);

        int maxThreads = 3;

        ExecutorService executor = Executors.newFixedThreadPool(5);


        Runnable task = () -> {

            if (activeThreads.incrementAndGet() <= maxThreads) {

                try {

                    System.out.println(Thread.currentThread().getName() + " is working...");

                    Thread.sleep((long) (Math.random() * 2000)); // Simulate work

                catch (InterruptedException e) {

                    Thread.currentThread().interrupt();

                finally {

                    activeThreads.decrementAndGet();

                }

            else {

                System.out.println(Thread.currentThread().getName() + " is denied access (rate limit exceeded).");

                activeThreads.decrementAndGet(); // Decrease count if denied

            }

        };


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

            executor.submit(task);

        }


        executor.shutdown();

    }

}


Key Points:

AtomicInteger tracks the number of active threads.

Threads exceeding the rate limit are denied access.


These examples cover various practical use cases for AtomicInteger and CountDownLatch, showcasing how they can be used in advanced multithreading scenarios to solve real-world problems effectively.

Like

0

Dislike

0

Comments

Recent

Lorem ipsum

Most Viewed

Dolor sit amet