java常用的并发工具类

1. 线程池相关工具类

1.1 ExecutorExecutorService
  • Executor:这是一个接口,用于定义提交任务的一种机制。通过 Executor,开发者可以将任务的执行与任务的提交分离。

  • ExecutorService:继承自 Executor 接口,增加了一些管理任务执行和生命周期的方法。ExecutorService 允许开发者管理线程池的生命周期,执行异步任务,并获取任务的结果。

    常见的实现类包括:

    • ThreadPoolExecutor:一个功能强大的线程池实现,允许配置线程池的核心线程数、最大线程数、任务队列等参数。
    • ScheduledThreadPoolExecutor:支持定时和周期性任务调度的线程池。

    示例代码:

    ExecutorService executor = Executors.newFixedThreadPool(10);
    executor.submit(() -> {
        System.out.println("Task executed");
    });
    executor.shutdown();
    
1.2 ForkJoinPool

ForkJoinPool 是 Java 7 引入的一种特殊的线程池,设计用于递归任务的并行执行。它基于工作窃取算法(Work-Stealing Algorithm),能够高效地处理那些可以分解成多个子任务的工作负载。

  • RecursiveTask:用于有返回值的递归任务。
  • RecursiveAction:用于没有返回值的递归任务。

示例代码:

ForkJoinPool forkJoinPool = new ForkJoinPool();
ForkJoinTask<Integer> task = forkJoinPool.submit(new RecursiveTaskExample());
Integer result = task.join();

2. 同步工具类

2.1 CountDownLatch

CountDownLatch 是一种同步工具类,允许一个或多个线程等待,直到其他线程完成一组操作。它通过一个计数器实现,当计数器的值降为零时,所有等待的线程将被唤醒。

  • 典型应用场景:用于确保某些活动直到其他所有依赖的活动完成之后再执行,例如等待多个线程完成计算后再汇总结果。

    示例代码:

    CountDownLatch latch = new CountDownLatch(3);
    
    Runnable task = () -> {
        System.out.println(Thread.currentThread().getName() + " is working");
        latch.countDown();
    };
    
    new Thread(task).start();
    new Thread(task).start();
    new Thread(task).start();
    
    latch.await();
    System.out.println("All tasks completed");
    
2.2 CyclicBarrier

CyclicBarrier 是另一种用于线程同步的工具类,允许一组线程互相等待,直到所有线程都到达某个共同的障碍点。CyclicBarrierCountDownLatch 的不同之处在于它可以重复使用,即在所有线程到达障碍点并执行完后,CyclicBarrier 可以被重置以供后续使用。

  • 典型应用场景:用于在并行处理时,确保多个线程在执行下一步操作之前达成同步,如并行分块处理。

    示例代码:

    CyclicBarrier barrier = new CyclicBarrier(3, () -> {
        System.out.println("All parties are arrived at barrier, let's play");
    });
    
    Runnable task = () -> {
        try {
            System.out.println(Thread.currentThread().getName() + " is waiting at barrier");
            barrier.await();
        } catch (Exception e) {
            e.printStackTrace();
        }
    };
    
    new Thread(task).start();
    new Thread(task).start();
    new Thread(task).start();
    
2.3 Semaphore

Semaphore 是一个计数信号量,它可以控制同时访问特定资源的线程数量。信号量主要用于管理对有限资源的访问,例如数据库连接池、文件系统等。

  • 典型应用场景:限制对某些资源的访问,例如只允许一次最多五个线程访问数据库。

    示例代码:

    Semaphore semaphore = new Semaphore(3);
    
    Runnable task = () -> {
        try {
            semaphore.acquire();
            System.out.println(Thread.currentThread().getName() + " got the permit");
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release();
            System.out.println(Thread.currentThread().getName() + " released the permit");
        }
    };
    
    new Thread(task).start();
    new Thread(task).start();
    new Thread(task).start();
    new Thread(task).start();
    new Thread(task).start();
    
2.4 ReentrantLock

ReentrantLock 是一个可重入的锁,提供了比 synchronized 更加灵活的锁机制。它允许显式地获取和释放锁,并提供了与 Condition 对象结合使用的功能,以实现更加复杂的线程间同步。

  • 典型应用场景:用于需要显式控制锁获取和释放的场景,特别是在需要尝试加锁或带超时的加锁操作时。

    示例代码:

    ReentrantLock lock = new ReentrantLock();
    Condition condition = lock.newCondition();
    
    Runnable task = () -> {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + " acquired the lock");
            condition.await();
            System.out.println(Thread.currentThread().getName() + " resumed");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    };
    
    new Thread(task).start();
    

3. 并发集合类

3.1 ConcurrentHashMap

ConcurrentHashMap 是线程安全的 HashMap 实现,它使用了一种细粒度的锁机制,允许多个线程并发地读写操作。与传统的 Hashtable 不同,ConcurrentHashMap 具有更好的并发性能,因为它不会对整个表加锁,而是对各个桶(bucket)进行细粒度加锁。

  • 典型应用场景:用于在高并发场景下存储和访问数据,例如缓存、计数器等。

    示例代码:

    ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
    map.put("key1", 1);
    map.put("key2", 2);
    System.out.println(map.get("key1"));
    
3.2 CopyOnWriteArrayList

CopyOnWriteArrayList 是一种线程安全的列表实现,它通过在每次修改时复制整个底层数组来实现线程安全。这种机制特别适合读多写少的场景,因为读操作无需加锁,且不会阻塞。

  • 典型应用场景:用于需要频繁读取但很少修改的列表场景,例如系统配置、事件监听器列表等。

    示例代码:

    CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
    list.add("Hello");
    list.add("World");
    for (String s : list) {
        System.out.println(s);
    }
    
3.3 BlockingQueue

BlockingQueue 是一种支持线程安全操作的队列,提供了阻塞的插入和移除方法。常见的实现包括 ArrayBlockingQueueLinkedBlockingQueuePriorityBlockingQueue 等。

  • 典型应用场景:用于生产者-消费者模式,生产者将数据放入队列,消费者从队列中获取数据进行处理。

    示例代码:

    BlockingQueue<String> queue = new LinkedBlockingQueue<>(10);
    
    new Thread(() -> {
        try {
            queue.put("data");
            System.out.println("Produced data");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();
    
    new Thread(() -> {
        try {
            String data = queue.take();
            System.out.println("Consumed " + data);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();
    

4. 原子类

4.1 AtomicInteger

AtomicInteger 是一个提供原子操作的 int 类型包装类,支持线程安全的递增、递减和更新操作。它通过底层的 CAS(Compare-And-Swap)操作实现线程安全。

  • 典型应用场景:用于计数器、标识符生成器等需要高并发下的原子操作场景。

    示例代码:

    AtomicInteger atomicInteger = new AtomicInteger(0);
    int newValue = atomicInteger.incrementAndGet();
    System.out.println(newValue);
    
4.2 AtomicBoolean, AtomicLong, `

AtomicReference`

  • AtomicBoolean:提供原子操作的 boolean 类型。
  • AtomicLong:提供原子操作的 long 类型。
  • AtomicReference:提供对引用对象的原子更新操作。

5. 并发辅助类

5.1 Exchanger

Exchanger 是一种同步点,两个线程可以在此点交换数据。线程在 Exchanger 上进行 exchange 操作时将数据传递给对方,并接收对方的数据。

  • 典型应用场景:用于两个线程之间的数据交换,如生产者和消费者之间的缓冲区交换。

    示例代码:

    Exchanger<String> exchanger = new Exchanger<>();
    
    new Thread(() -> {
        try {
            String data = "Data from Thread A";
            String received = exchanger.exchange(data);
            System.out.println("Thread A received: " + received);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();
    
    new Thread(() -> {
        try {
            String data = "Data from Thread B";
            String received = exchanger.exchange(data);
            System.out.println("Thread B received: " + received);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();
    
5.2 Phaser

Phaser 是一种更灵活的同步屏障,允许线程动态地参与或退出同步。它是 CyclicBarrierCountDownLatch 的增强版本,适用于复杂的分阶段任务。

  • 典型应用场景:用于需要分阶段同步或变动参与者的场景。

    示例代码:

    Phaser phaser = new Phaser(1); // 注册主线程
    
    for (int i = 0; i < 3; i++) {
        phaser.register();
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + " arrived at phase 1");
            phaser.arriveAndAwaitAdvance();
            System.out.println(Thread.currentThread().getName() + " arrived at phase 2");
            phaser.arriveAndAwaitAdvance();
        }).start();
    }
    
    phaser.arriveAndDeregister(); // 主线程到达并注销
    

总结

Java 提供了丰富的并发工具类来帮助开发者应对多线程编程的挑战。从线程池管理到同步机制,再到并发集合和原子操作,每种工具类都有其特定的应用场景和优点,这些工具类位于 java.util.concurrent 包中,涵盖了从线程池、同步机制到并发集合的广泛功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Flying_Fish_Xuan

你的鼓励将是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值