线程池 | java中的多线程

在 《Java异步编程 | CompletableFuture--实现复杂的异步控制流
》中,我们提到了 通过 自定义线程池 , 用于管理 异步任务的执行,避免频繁创建和销毁线程,提高性能。

本文将整理并介绍一些 Java 中常见的 多线程创建方式,用于 更好地理解和选择 合适的线程管理策略

本文整理了下述5种 创建多线程 的方式

  1. 实现 Runnable 接口
  2. 继承 Thread 类
  3. 使用 Callable 和 FutureTask
  4. 使用线程池(ExecutorService)
  5. CompletableFuture

一、实现 Runnable 接口

  • 方式:通过 实现 Runnable 接口的 run() 方法 ,定义线程要执行的任务,然后将 Runnable 对象 传入 Thread 构造函数,最后调用 start() 方法启动线程。
  • 优点:可以避免继承 Thread 类的限制,Runnable 可以被 多个线程共享
  • 代码示例
class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("Thread is running");}
}public class Main {public static void main(String[] args) {Thread thread = new Thread(new MyRunnable());thread.start();}
}

二、继承 Thread

  • 方式:直接 继承 Thread 类,并重写 run() 方法,创建 子类对象 并调用 start() 方法启动线程。
  • 优点:简单直观,适用于线程功能比较单一的情况。
  • 缺点:Java 不支持多重继承,因此如果已经继承了其他类,就不能再继承 Thread 类。
  • 代码示例
class MyThread extends Thread {@Overridepublic void run() {System.out.println("Thread is running");}
}public class Main {public static void main(String[] args) {MyThread thread = new MyThread();thread.start();}
}

三、使用 CallableFutureTask

  • 方式Callable 接口与 Runnable 类似,但它可以 返回结果抛出异常。通过 FutureTask 来包装 Callable 对象,再通过 Thread 启动。
  • 优点:可以获取任务的 执行结果,并处理异常。
  • 代码示例
class MyCallable implements Callable<Integer> {@Overridepublic Integer call() throws Exception {return 100;}
}public class Main {public static void main(String[] args) throws Exception {FutureTask<Integer> task = new FutureTask<>(new MyCallable());Thread thread = new Thread(task);thread.start();Integer result = task.get(); // 获取任务执行结果System.out.println("Result: " + result);}
}

四、使用线程池(ExecutorService

  • 方式:线程池通过 ExecutorService 提供一个更高层的 API,管理线程的 创建、调度和销毁。可以使用线程池来提交 RunnableCallable 任务,避免手动管理线程,特别适合 处理大量并发任务
  • 优点:线程池能够重用线程,避免线程的频繁创建和销毁,提高了效率;还可以 控制并发线程的数量
  • 代码示例
class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("Thread is running in a thread pool");}
}public class Main {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(10); // 创建一个大小为10的线程池executor.submit(new MyRunnable()); // 提交任务executor.shutdown(); // 关闭线程池}
}

(一) 核心方法

  • submit(Runnable task):提交一个没有返回值的任务。
  • submit(Callable<T> task):提交一个有返回值的任务,返回一个 Future<T> 对象,可以通过 get() 方法获取任务的执行结果。
  • invokeAll(Collection<? extends Callable<T>> tasks):提交一组任务并等待所有任务完成,返回每个任务的结果。
  • invokeAny(Collection<? extends Callable<T>> tasks):提交一组任务,返回最先完成的任务的结果。
  • shutdown():启动优雅关闭,停止接收新的任务,并等待现有任务完成。
  • shutdownNow():立即关闭线程池,尝试中断所有正在执行的任务并返回待执行的任务列表。

(二) ExecutorService 的实现类

Java 提供了几种常用的线程池实现类:

1. newFixedThreadPool(int nThreads)
  • 创建一个固定大小的线程池,线程池中始终有固定数量的线程。适合于处理需要固定线程数的任务。
  • 如果线程池中有线程空闲,新的任务将由空闲线程执行;如果线程池已满,新任务将被放入任务队列等待。

示例

ExecutorService executor = Executors.newFixedThreadPool(3);
2. newCachedThreadPool()
  • 创建一个可以根据需要创建新线程的线程池,如果线程池中的线程空闲超过60秒就会被回收。适合于执行大量短时间的异步任务。
  • 线程池的大小根据系统需求动态调整。

示例

ExecutorService executor = Executors.newCachedThreadPool();
3. newSingleThreadExecutor()
  • 创建一个只有一个线程的线程池,所有提交的任务将顺序执行。适合于需要按顺序执行任务的场景。

示例

ExecutorService executor = Executors.newSingleThreadExecutor();
4. newScheduledThreadPool(int corePoolSize)
  • 创建一个固定大小的线程池,适用于定时任务和周期性任务的执行。

示例

ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
executor.schedule(() -> {System.out.println("Scheduled task executed");
}, 1, TimeUnit.SECONDS);

(三) ExecutorService 的作用

  1. 管理线程池ExecutorService 负责创建和管理一个或多个线程池,它从池中获取线程来执行任务。与直接创建线程(如通过 new Thread())相比,使用线程池更加高效和灵活,特别是在处理大量短小任务时,线程池能有效避免线程频繁创建和销毁的开销。
  2. 任务提交: 它通过 submit() 方法将任务提交给线程池执行,返回一个 Future 对象,Future 允许我们获取任务的执行结果或取消任务。
  3. 任务调度ExecutorService 提供了强大的任务调度功能,可以安排任务在未来某个时刻执行,或者定期执行任务。例如,使用 schedule() 方法,任务可以按照固定的延迟执行或以固定的周期重复执行。
  4. 线程复用: 线程池内部维护了一组线程,线程池中的线程可以被复用,执行完一个任务后,线程会返回池中准备执行下一个任务。这样避免了每次执行任务都需要创建和销毁线程的性能消耗。
  5. 优雅关闭ExecutorService 提供了 shutdown() 方法来优雅地关闭线程池,这样线程池中的线程会完成正在执行的任务并终止,新的任务将不会被接受。它还提供了 shutdownNow() 方法,用于立即关闭线程池并尝试停止所有正在执行的任务。

五、CompletableFuture(本质也是线程池)

有关CompletableFuture,详见 《Java异步编程 | CompletableFuture–实现复杂的异步控制流》

  • 方式CompletableFuture 是 Java 8 引入的 API,用于处理异步编程。它可以非常方便地处理异步任务之间的依赖关系,并支持链式调用。它默认使用 ForkJoinPool 来执行任务,提供了比 Future 更强大的功能。
  • 优点:支持异步编程,并能链式调用,简化了异步任务的处理。
  • 代码示例
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {System.out.println("Asynchronous task");
});future.thenRun(() -> {System.out.println("Another task after first one");
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/67782.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Javaweb之css

css的三种引入方式 1内行式 2.内嵌式 3.外部样式表 内行式和内嵌式 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0&quo…

SQLmap 注入-03 获得用户信息

1: Sqlmap 先进入库&#xff0c;然后进入table, 然后列出column: sqlmap -u "http://192.168.56.133/mutillidae/index.php?pageuser-info.php&usernamexiaosheng&passwordabc&user-info-php-submit-buttonViewAccountDetails" --batch -p username -D …

mac 安装 python2

官网下载2.7&#xff1a; Python Release Python 2.7.18 | Python.org 查找地址&#xff1a; which python2 # /usr/local/bin/python2 设置 npm 使用 Python 2&#xff08;新建窗口&#xff09;&#xff1a; npm config set python /usr/local/bin/python2 验证 Python 版…

Jupyter notebook中运行dos指令运行方法

Jupyter notebook中运行dos指令运行方法 目录 Jupyter notebook中运行dos指令运行方法一、DOS(磁盘操作系统&#xff09;指令介绍1.1 DOS介绍1.2 DOS指令1.2.1 DIR - 显示当前目录下的文件和子目录列表。1.2.2 CD 或 CHDIR - 改变当前目录1.2.3 使用 CD .. 可以返回上一级目录1…

基于注解实现去重表消息防止重复消费

基于注解实现去重表消息防止重复消费 1. 背景/问题 在分布式系统中&#xff0c;消息队列&#xff08;如RocketMQ、Kafka&#xff09;的 消息重复消费 是常见问题&#xff0c;主要原因包括&#xff1a; 网络抖动&#xff1a;生产者或消费者因网络不稳定触发消息重发。消费者超…

Biotin sulfo-N-hydroxysuccinimide ester ;生物素磺基-N-羟基琥珀酰亚胺酯;生物素衍生物;190598-55-1

一、生物素及其衍生物的概述 生物素衍生物是指在生物素&#xff08;Vitamin H或B7&#xff09;分子基础上进行化学修饰得到的衍生化合物。这些衍生化合物在生物医学研究、临床诊断和药物开发等领域有着广泛的应用。 生物素&#xff08;Biotin&#xff09;是一种水溶性维生素&a…

Ubuntu如何安装redis服务?

环境&#xff1a; Ubuntu22.04 WSL2 问题描述&#xff1a; 如何安装redis服务&#xff1f; 解决方案&#xff1a; 1.在 Linux 上&#xff08;如 Ubuntu/Debian&#xff09;安装 1.通过包管理工具安装 Redis 服务器&#xff1a; sudo apt update sudo apt install redis…

Datawhale组队学习笔记task2——leetcode面试题

文章目录 写在前面Day5题目1.0112.路径总和解答2.0113路径总和II解答3.0101.对称二叉树解答 Day6题目1.0124.二叉树中的最大路径和解答2.0199.二叉树的右视图解答3.0226.翻转二叉树解答 Day7题目1.0105.从前序与中序遍历序列构造二叉树解答2.0098.验证二叉搜索树解答3.0110.平衡…

Slate文档编辑器-Node节点与Path路径映射

Slate文档编辑器-Node节点与Path路径映射 在之前我们聊到了slate中的Decorator装饰器实现&#xff0c;装饰器可以为我们方便地在编辑器渲染调度时处理range的渲染&#xff0c;这在实现搜索替换、代码高亮等场景非常有用。那么在这篇文章中&#xff0c;我们聊一下Node节点与Pat…

麒麟系统中删除权限不够的文件方法

在麒麟系统中删除权限不够的文件&#xff0c;可以尝试以下几种方法&#xff1a; 通过修改文件权限删除 打开终端&#xff1a;点击左下角的“终端”图标&#xff0c;或者通过搜索功能找到并打开终端 。定位文件&#xff1a;使用cd命令切换到文件所在的目录 。修改文件权限&…

Kotlin语言的正则表达式

Kotlin语言中的正则表达式 引言 正则表达式作为一种强大的文本处理工具&#xff0c;广泛应用于字符串匹配、数据验证、文本搜索等场景。在Kotlin语言中&#xff0c;正则表达式的应用同样得到了广泛关注。Kotlin不仅具备与Java相同的正则表达式功能优势&#xff0c;还提供了更…

Flask简介与安装以及实现一个糕点店的简单流程

目录 1. Flask简介 1.1 Flask的核心特点 1.2 Flask的基本结构 1.3 Flask的常见用法 1.3.1 创建Flask应用 1.3.2 路由和视图函数 1.3.3 动态URL参数 1.3.4 使用模板 1.4 Flask的优点 1.5 总结 2. Flask 环境创建 2.1 创建虚拟环境 2.2 激活虚拟环境 1.3 安装Flask…

RFID系统安全认证协议及防碰撞算法研究(RFID Security)

目录 1.摘要 2.引言 3.前人研究成果 3.1 RFID系统协议模型 3.2 RFID系统安全认证协议分类 3.3 RFID安全认证协议及其研究 3.3.1 超轻量级安全认证协议及其研究 3.3.2 轻量级安全认证协议及其研究 3.3.2 中量级安全认证协议及其研究 3.3.3 重量级安全认证协议及其研究…

Docker 实现MySQL 主从复制

一、拉取镜像 docker pull mysql:5.7相关命令&#xff1a; 查看镜像&#xff1a;docker images 二、启动镜像 启动mysql01、02容器&#xff1a; docker run -d -p 3310:3306 -v /root/mysql/node-1/config:/etc/mysql/ -v /root/mysql/node-1/data:/var/lib/mysql -e MYS…

Spring MVC:设置响应

目录 引言 1. 返回静态页面 1.1 Spring 默认扫描路径 1.2 RestController 1.2.1 Controller > 返回页面 1.2.2 ResponseBody 2. 返回 HTML 2.1 RequestMapping 2.1.1 produces(修改响应的 Content-Type) 2.1.2 其他属性 3. 返回 JSON 4. 设置状态码 4.1 HttpSer…

在Windows/Linux/MacOS C++程序中打印崩溃调用栈和局部变量信息

打印崩溃调用栈和局部变量信息的方法有所不同。以下是针对 Windows、Linux 和 MacOS 的示例代码。 Windows 在 Windows 上&#xff0c;可以使用 Windows API 来捕获异常并打印调用栈。 #include <windows.h> #include <DbgHelp.h> #include <stdio.h> #in…

基于python+Django+mysql鲜花水果销售商城网站系统设计与实现

博主介绍&#xff1a;黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者&#xff0c;CSDN博客专家&#xff0c;在线教育专家&#xff0c;CSDN钻石讲师&#xff1b;专注大学生毕业设计教育、辅导。 所有项目都配有从入门到精通的基础知识视频课程&#xff…

提示词的艺术----AI Prompt撰写指南(个人用)

提示词的艺术 写在前面 制定提示词就像是和朋友聊天一样&#xff0c;要求我们能够清楚地表达问题。通过这个过程&#xff0c;一方面要不断练习提高自己地表达能力&#xff0c;另一方面还要锻炼自己使用更准确精炼的语言提出问题的能力。 什么样的提示词有用&#xff1f; 有…

MySQL管理事务处理

目录 1、事务处理是什么 2、控制事务处理 &#xff08;1&#xff09;事务的开始和结束 &#xff08;2&#xff09;回滚事务 &#xff08;3&#xff09;使用COMMIT &#xff08;4&#xff09;使用保留点 &#xff08;5&#xff09;结合存储过程的完整事务例子 3、小结 …

oneplus3t-lineageos-16.1编译-android9,

oneplus3t-lineageos-16.1编译-android9 oneplus3t 前提 救砖线刷 OnePlus3t android9 OTA卡刷 OnePlus3t android9 APatch root debian11(标准GNU工具集) arm 工具盘(chroot 风格rootfs, 含有 比如sshd 、gdb) : tinan/eadb.git 本仓库开发已经完毕,使用请直接从4.2开始…