当前位置: 首页 > ai >正文

线程池与并发工具:让并发编程更简单、高效!

全文目录:

    • 开篇语
    • 前言
      • 一、Executor框架与线程池
        • 1.1 Executor 框架概述
        • 1.2 创建线程池
          • 代码示例:使用 `ExecutorService` 创建线程池
      • 二、Callable 与 Future 接口
        • 2.1 `Callable` 接口
        • 2.2 `Future` 接口
          • 代码示例:使用 `Callable` 和 `Future`
      • 三、CountDownLatch、CyclicBarrier 等同步工具类
        • 3.1 `CountDownLatch`
          • 代码示例:使用 `CountDownLatch`
        • 3.2 `CyclicBarrier`
          • 代码示例:使用 `CyclicBarrier`
      • 四、ForkJoin框架与并行计算
        • 4.1 `ForkJoin` 框架的基本概念
          • 代码示例:使用 `ForkJoinPool`
      • 总结:高效并发与线程控制
    • 文末

开篇语

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

  在多线程编程中,线程的创建和销毁是非常耗费资源的,频繁地创建和销毁线程会导致性能下降。为了提高并发性能,Java 提供了线程池和其他并发工具类,这些工具能够帮助我们更高效地管理和执行线程,减少资源的浪费。今天我们将深入探讨 Executor框架与线程池Callable与Future接口CountDownLatch、CyclicBarrier等同步工具类,以及 ForkJoin框架与并行计算


一、Executor框架与线程池

Java 提供了 Executor 框架,用于管理和控制线程池。线程池能够复用线程,避免了每次任务提交时都要创建新线程的开销,从而提升了程序的性能。

1.1 Executor 框架概述

Executor 是一个接口,定义了用于执行异步任务的方法。ExecutorServiceExecutor 的子接口,它定义了更丰富的线程池管理和任务控制功能。

常见的线程池实现类包括:

  • ThreadPoolExecutor:最常用的线程池实现,能够自定义线程池的各项参数。
  • ScheduledThreadPoolExecutor:支持定时任务的线程池。
  • Executors:提供了静态方法来快速创建各种线程池。
1.2 创建线程池

通过 Executors 类的静态工厂方法,可以创建不同类型的线程池。常见的线程池类型包括:

  • newFixedThreadPool(int nThreads):创建一个固定大小的线程池。
  • newCachedThreadPool():创建一个可以根据需要创建新线程的线程池,空闲线程会被回收。
  • newSingleThreadExecutor():创建一个单线程线程池。
代码示例:使用 ExecutorService 创建线程池
import java.util.concurrent.*;public class ExecutorExample {public static void main(String[] args) {// 创建一个固定大小的线程池ExecutorService executorService = Executors.newFixedThreadPool(3);// 提交任务给线程池executorService.submit(() -> {System.out.println("任务正在执行,线程名:" + Thread.currentThread().getName());});// 关闭线程池executorService.shutdown();}
}

  在这个例子中,我们创建了一个固定大小的线程池 executorService,并提交了一个任务。线程池管理着任务的执行和线程的复用,避免了频繁创建和销毁线程的开销。


二、Callable 与 Future 接口

在使用线程池执行任务时,Runnable 只能返回 void,它不允许任务执行的结果返回给调用者。如果我们希望任务有返回值,或者需要捕获异常,可以使用 Callable 接口和 Future 接口。

2.1 Callable 接口

CallableRunnable 类似,都是用于表示任务,但不同之处在于 Callable 允许任务执行有返回值,并且可以抛出异常。call() 方法返回任务的结果。

2.2 Future 接口

Future 是用于表示异步计算结果的接口。通过 Future 对象,我们可以检查任务是否完成,取消任务,或者获取任务的结果。

代码示例:使用 CallableFuture
import java.util.concurrent.*;public class CallableFutureExample {public static void main(String[] args) throws InterruptedException, ExecutionException {ExecutorService executorService = Executors.newFixedThreadPool(2);// 创建一个 Callable 任务Callable<Integer> task = () -> {System.out.println("任务开始,线程名:" + Thread.currentThread().getName());Thread.sleep(2000); // 模拟任务执行return 123; // 返回结果};// 提交任务并获取 Future 对象Future<Integer> future = executorService.submit(task);// 获取任务结果Integer result = future.get();  // 阻塞,直到任务完成并返回结果System.out.println("任务执行结果:" + result);executorService.shutdown();}
}

  在这个例子中,我们创建了一个 Callable 任务,并通过 submit() 方法将其提交给线程池。future.get() 方法会阻塞并等待任务执行完毕,最终返回结果。


三、CountDownLatch、CyclicBarrier 等同步工具类

Java 提供了多种同步工具类,用于协调多线程之间的执行顺序。常见的同步工具类包括 CountDownLatchCyclicBarrier

3.1 CountDownLatch

CountDownLatch 用于使一个或多个线程等待直到在其他线程中执行的一组操作完成。在某些情况下,多个线程必须等待某些任务完成后才能继续执行。

  • await():让当前线程等待。
  • countDown():减少计数器的值,当计数器为零时,所有等待线程会被释放。
代码示例:使用 CountDownLatch
import java.util.concurrent.*;public class CountDownLatchExample {public static void main(String[] args) throws InterruptedException {int taskCount = 3;CountDownLatch latch = new CountDownLatch(taskCount);// 启动多个线程for (int i = 0; i < taskCount; i++) {int taskId = i + 1;new Thread(() -> {try {System.out.println("任务 " + taskId + " 正在执行...");Thread.sleep(1000);  // 模拟任务执行latch.countDown();  // 任务完成,计数器减1} catch (InterruptedException e) {e.printStackTrace();}}).start();}latch.await();  // 等待所有任务完成System.out.println("所有任务完成,继续执行主线程");}
}

  在这个例子中,主线程通过 latch.await() 等待所有子线程执行完成。每个子线程完成任务后通过 latch.countDown() 减少计数器,直到所有子线程完成,主线程才继续执行。

3.2 CyclicBarrier

CyclicBarrier 用于让一组线程在某个公共屏障点上等待,直到所有线程都到达屏障点为止。与 CountDownLatch 不同的是,CyclicBarrier 在多次使用时会被重置。

代码示例:使用 CyclicBarrier
import java.util.concurrent.*;public class CyclicBarrierExample {public static void main(String[] args) throws InterruptedException {int parties = 3;CyclicBarrier barrier = new CyclicBarrier(parties, () -> System.out.println("所有线程到达屏障点,继续执行"));// 启动多个线程for (int i = 0; i < parties; i++) {int threadId = i + 1;new Thread(() -> {try {System.out.println("线程 " + threadId + " 到达屏障点");barrier.await();  // 等待其他线程到达屏障点} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}}).start();}}
}

  在这个例子中,CyclicBarrier 的每个线程都会等待其他线程到达屏障点,直到所有线程都到达,屏障才会被释放,允许所有线程继续执行。


四、ForkJoin框架与并行计算

ForkJoin 框架是 Java 7 引入的一个新框架,专门用于并行任务的分解和执行。它适用于需要分解为多个子任务的任务,像是大数据计算、图像处理、并行算法等。

4.1 ForkJoin 框架的基本概念
  • Fork:将任务分解为多个子任务。
  • Join:等待所有子任务完成,并将结果合并。

ForkJoinPoolForkJoin 框架的核心类,用于执行和管理分解后的任务。

代码示例:使用 ForkJoinPool
import java.util.concurrent.*;public class ForkJoinExample {public static void main(String[] args) throws InterruptedException, ExecutionException {ForkJoinPool forkJoinPool = new ForkJoinPool();// 定义一个递归任务RecursiveTask<Integer> task = new RecursiveTask<>() {@Overrideprotected Integer compute() {return 1 + 2;  // 简单示例:返回 1 + 2}};// 提交任务并获取结果Future<Integer> result = forkJoinPool.submit(task);System.out.println("任务结果:" + result.get());  // 输出任务执行结果}
}

  在这个例子中,我们使用 ForkJoinPool 提交了一个递归任务,它返回了 1 + 2 的结果。ForkJoin 框架特别适合用来处理需要并行计算的任务。


总结:高效并发与线程控制

  通过使用线程池、同步工具类和 ForkJoin 框架,Java 为我们提供了强大的并发编程支持。Executor 框架帮助我们管理线程池,CallableFuture 接口使得任务可以有返回值,CountDownLatchCyclicBarrier 用于协调线程之间的同步,而 ForkJoin 框架则能高效地进行并行计算。

  掌握这些并发工具,你就能在多线程编程中更加游刃有余,构建出高效、可扩展的并发应用!

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。


版权声明:本文由作者原创,转载请注明出处,谢谢支持!

http://www.xdnf.cn/news/13067.html

相关文章:

  • CodeRider 2.0 体验手记:当 AI 编程照进现实,颠覆想象的开发之旅
  • 【51单片机】4. 模块化编程与LCD1602Debug
  • 中国大学本科专业采用‌学科门类—专业类—具体专业‌三级体系
  • 【DAY44】预训练模型
  • sql语句执行流程
  • 指令管理—弹幕/礼物/快捷键—抖音直播伴侣—使用教程
  • omi开源程序是AI 可穿戴设备的源码。戴上它,说话,转录,自动完成
  • 用大白话解释一下“高基数特征”
  • java+webstock
  • 什么是API调用?通俗解释+实际应用场景详解
  • 【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!
  • PAN/FPN
  • Flotherm许可的并发用户数限制
  • 【案例解析】一次 TIME_WAIT 导致 TPS 断崖式下降的排查与优化
  • ThreadLocal 源码
  • RabbitMq安装
  • deepseek: GPU 配套
  • 联邦学习同态加密以及常见问题
  • Vue动态/异步组件
  • 1991-2024年上市公司个股换手率数据
  • Haption 力反馈遥操作机器人:6 自由度 + 低延迟响应,解锁精准远程操控体验
  • 设置Outlook关闭时最小化
  • mybatisX的使用,简化springboot的开发,不用再写entity、mapper以及service了!
  • JDK 17 序列化是怎么回事
  • Prompt‏ 工程和优化技巧
  • 产品经理课程(十三)
  • SE(Secure Element)加密芯片与MCU协同工作的典型流程
  • 在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
  • Origin图像数字化工具——如何复制其他人的图表作为对比数据
  • Linux 下部署安装docker