Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • MacOS
  • Linux
  • Windows
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • MacOS
  • Linux
  • Windows
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java基础

    • Java概述
    • Java语法
    • 面向对象编程
    • Java数组
    • String字符串
    • 异常处理
  • Java集合

    • Java集合概述
    • ArrayList
    • LinkedList
    • HashMap
    • LinkedHashMap
    • HashSet
    • TreeMap
    • Queue&Deque
  • Java并发

    • Java并发概述
    • 线程与进程
    • Thread类与线程生命周期
    • 线程安全
    • synchronized关键字
    • volatile关键字
    • Java内存模型(JMM)
    • 线程间通信
    • 线程池
    • 并发工具类
      • 1. CountDownLatch
      • 2. CyclicBarrier
      • 3. Semaphore
      • 4. ReentrantLock
      • 5. Exchanger
      • 6. Phaser
      • 7. 总结
    • 原子操作类Atomic
    • 并发锁
    • 并发容器
    • ConcurrentHashMap
    • BlockingQueue
    • CopyOnWriteArrayList
    • ThreadLocal
    • Fork/Join框架
    • ScheduledThreadPoolExecutor
    • CompletableFuture
  • Java IO

    • Java IO概述
  • JVM

    • JVM概述
  • Java
  • Java并发
Wray
2024-10-31
目录

并发工具类

Java 提供了丰富的并发工具类来简化多线程编程,尤其是在 java.util.concurrent 包中。这些工具类能够有效解决线程间协作、同步等问题,帮助开发者编写更加安全、健壮的并发程序。

# 1. CountDownLatch

  • 概念:CountDownLatch 是一个同步辅助工具,允许一个或多个线程等待其他线程完成操作。通过一个计数器来实现,计数器初始值由线程数量决定。
  • 使用场景:适用于需要等待多个线程完成某些操作之后,再继续执行的场景。例如,主线程等待多个子线程初始化完毕再开始工作。
  • 示例代码:
    CountDownLatch latch = new CountDownLatch(3);
    
    Runnable worker = () -> {
        try {
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName() + " finished work.");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            latch.countDown();
        }
    };
    
    for (int i = 0; i < 3; i++) {
        new Thread(worker).start();
    }
    
    try {
        latch.await();
        System.out.println("All threads have finished work, proceeding...");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    
    在这个例子中,主线程会等待所有子线程执行完毕后才会继续。

# 2. CyclicBarrier

  • 概念:CyclicBarrier 是一个同步辅助工具,它允许一组线程相互等待,直到它们都到达某个公共屏障点。与 CountDownLatch 不同的是,CyclicBarrier 可以被重复使用。
  • 使用场景:适用于一组线程需要相互等待,直到所有线程都达到某个同步点的场景,例如并行计算中分阶段的结果合并。
  • 示例代码:
    CyclicBarrier barrier = new CyclicBarrier(3, () -> {
        System.out.println("All parties have arrived, proceeding to the next step...");
    });
    
    Runnable worker = () -> {
        try {
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName() + " arrived at the barrier.");
            barrier.await();
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
    };
    
    for (int i = 0; i < 3; i++) {
        new Thread(worker).start();
    }
    
    在这个例子中,所有线程到达屏障点后会执行指定的 Runnable,然后继续执行后续任务。

# 3. Semaphore

  • 概念:Semaphore 是一种用于控制同时访问某特定资源的线程数量的工具,它通过许可证的方式来控制访问权限。
  • 使用场景:适用于限制对资源的并发访问数量,例如控制对数据库连接的访问数目。
  • 示例代码:
    Semaphore semaphore = new Semaphore(2);
    
    Runnable worker = () -> {
        try {
            semaphore.acquire();
            System.out.println(Thread.currentThread().getName() + " acquired a permit.");
            Thread.sleep(2000);
            System.out.println(Thread.currentThread().getName() + " released a permit.");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release();
        }
    };
    
    for (int i = 0; i < 5; i++) {
        new Thread(worker).start();
    }
    
    在这个例子中,最多只能有两个线程同时获取许可证,其余线程将被阻塞。

# 4. ReentrantLock

  • 概念:ReentrantLock 是一个可重入的互斥锁,与 synchronized 相比,它具有更高的灵活性和更多的控制选项。
  • 使用场景:适用于需要显式锁定和解锁,并且需要尝试锁、超时锁等高级功能的场景。
  • 示例代码:
    ReentrantLock lock = new ReentrantLock();
    
    Runnable worker = () -> {
        try {
            if (lock.tryLock(1000, TimeUnit.MILLISECONDS)) {
                try {
                    System.out.println(Thread.currentThread().getName() + " acquired the lock.");
                    Thread.sleep(2000);
                } finally {
                    lock.unlock();
                    System.out.println(Thread.currentThread().getName() + " released the lock.");
                }
            } else {
                System.out.println(Thread.currentThread().getName() + " could not acquire the lock.");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    };
    
    for (int i = 0; i < 3; i++) {
        new Thread(worker).start();
    }
    
    在这个例子中,线程尝试获取锁,若成功则执行相应操作,最后释放锁。

# 5. Exchanger

  • 概念:Exchanger 是一个用于在线程间交换数据的同步工具。它提供了一个同步点,两个线程可以在这个同步点交换数据。
  • 使用场景:适用于需要在线程之间交换数据的场景,例如两个线程协作处理任务,一个生产数据,另一个使用数据。
  • 示例代码:
    Exchanger<String> exchanger = new Exchanger<>();
    
    Runnable producer = () -> {
        try {
            String data = "Data from Producer";
            System.out.println("Producer is exchanging: " + data);
            String response = exchanger.exchange(data);
            System.out.println("Producer received: " + response);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    };
    
    Runnable consumer = () -> {
        try {
            String receivedData = exchanger.exchange("Data from Consumer");
            System.out.println("Consumer received: " + receivedData);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    };
    
    new Thread(producer).start();
    new Thread(consumer).start();
    
    在这个例子中,生产者和消费者在线程间交换数据,只有在双方都准备好后才会交换。

# 6. Phaser

  • 概念:Phaser 是一种用于多阶段同步的工具,类似于 CyclicBarrier,但它支持更为复杂的阶段同步。它允许线程动态地加入或离开同步。
  • 使用场景:适用于多阶段任务的同步控制,特别是在需要动态控制参与线程数的场景。

# 7. 总结

Java 中的并发工具类为多线程编程提供了强大的支持,从 CountDownLatch 到 CyclicBarrier,再到 Semaphore、ReentrantLock、Exchanger 和 Phaser,每个工具类都有其独特的应用场景。通过合理使用这些工具类,可以有效地简化线程之间的协作与同步,提升多线程程序的可维护性和健壮性。理解并发工具类的特性和适用场景,对于编写高效、可靠的并发程序至关重要。

上次更新: 2024/11/01, 13:45:14
线程池
原子操作类Atomic

← 线程池 原子操作类Atomic→

Copyright © 2023-2024 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式