Java 创建线程的方式有哪几种
在 Java 中,创建线程的方式有四种,分别是:继承 Thread
类、实现 Runnable
接口、使用 Callable
和 Future
、使用线程池。以下是详细的解释和通俗的举例:
1. 继承 Thread
类
通过继承 Thread
类并重写 run()
方法来创建线程。
步骤:
- 创建一个
Thread
类的子类,重写run()
方法,定义线程执行的任务。 - 创建该子类的实例,并调用
start()
方法启动线程。
代码示例:
class MyThread extends Thread {@Overridepublic void run() {System.out.println("Thread is running...");}
}public class ThreadExample {public static void main(String[] args) {MyThread thread = new MyThread(); // 创建线程对象thread.start(); // 启动线程}
}
解释:
MyThread
类继承了Thread
类,重写了run()
方法,run()
方法里是线程执行的任务。- 调用
start()
方法启动线程,start()
方法会调用run()
方法,线程开始执行。
优点:
- 代码简单,适合不需要线程共享资源的场景。
缺点:
- 继承
Thread
类无法再继承其他类,因为 Java 不支持多重继承。
2. 实现 Runnable
接口
创建一个实现了 Runnable
接口的类,并实现其 run()
方法。然后将该实例作为参数传递给 Thread
对象来创建线程。
步骤:
- 创建一个实现了
Runnable
接口的类,并重写run()
方法。 - 创建
Runnable
实例,将其传递给Thread
构造方法。 - 调用
start()
启动线程。
代码示例:
class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("Runnable thread is running...");}
}public class RunnableExample {public static void main(String[] args) {MyRunnable myRunnable = new MyRunnable(); // 创建Runnable对象Thread thread = new Thread(myRunnable); // 将Runnable对象传递给Threadthread.start(); // 启动线程}
}
解释:
MyRunnable
类实现了Runnable
接口,并重写了run()
方法,定义线程执行的任务。Thread
构造方法接收Runnable
对象,调用start()
启动线程。
优点:
- 适用于多个线程共享同一个
Runnable
对象的场景。 - 可以避免
Thread
类的单继承限制,Runnable
实现类可以继承其他类。
缺点:
- 线程任务无法返回结果或抛出异常。
3. 使用 Callable
和 Future
接口
Callable
接口与 Runnable
接口类似,但它能够返回结果,并且可以抛出异常。通过 ExecutorService
来管理线程池,并提交 Callable
任务获取 Future
对象,以便在未来某个时刻获取任务的计算结果。
步骤:
- 创建实现
Callable
接口的类,重写call()
方法,定义线程任务,并返回结果。 - 使用
ExecutorService
提交任务,返回一个Future
对象,可以用来获取任务执行的结果。
代码示例:
import java.util.concurrent.*;class MyCallable implements Callable<Integer> {@Overridepublic Integer call() throws Exception {System.out.println("Callable thread is running...");return 42; // 返回结果}
}public class CallableExample {public static void main(String[] args) throws Exception {ExecutorService executor = Executors.newSingleThreadExecutor(); // 创建线程池MyCallable myCallable = new MyCallable();Future<Integer> future = executor.submit(myCallable); // 提交任务// 获取任务的执行结果Integer result = future.get();System.out.println("Result: " + result);executor.shutdown(); // 关闭线程池}
}
解释:
MyCallable
实现了Callable
接口,重写了call()
方法,返回结果42
。- 使用
ExecutorService
来创建线程池并提交Callable
任务。 future.get()
会阻塞并返回任务执行的结果。
优点:
- 适用于需要任务返回结果或需要处理异常的场景。
ExecutorService
提供了线程池管理,线程复用,提高了效率。
缺点:
- 使用
Future.get()
时会阻塞,直到任务完成并返回结果。
4. 使用线程池 (ExecutorService
)
通过使用 ExecutorService
来创建和管理线程池,并提交任务。线程池允许线程复用,避免了频繁创建和销毁线程的开销。
步骤:
- 使用
ExecutorService
创建线程池,通常使用Executors
类来创建。 - 提交任务到线程池执行,可以提交
Runnable
或Callable
任务。
代码示例:
import java.util.concurrent.*;class MyRunnableTask implements Runnable {@Overridepublic void run() {System.out.println("Task is running in thread pool...");}
}public class ExecutorServiceExample {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(2); // 创建线程池,最多2个线程executor.submit(new MyRunnableTask()); // 提交任务executor.submit(new MyRunnableTask()); // 提交另一个任务executor.shutdown(); // 关闭线程池}
}
解释:
- 使用
Executors.newFixedThreadPool(2)
创建了一个最多包含两个线程的线程池。 - 提交多个
Runnable
任务到线程池,线程池负责线程的创建和管理。 shutdown()
方法用于关闭线程池。
优点:
- 可以复用线程,避免了每次创建新线程的开销。
- 线程池可以根据系统资源动态调整线程数量,适用于高并发场景。
缺点:
- 需要管理线程池的生命周期,避免线程池资源泄漏。
总结
- 继承
Thread
类:直接继承并重写run()
方法,适合简单场景,但无法继承其他类。 - 实现
Runnable
接口:实现Runnable
接口的类并重写run()
方法,适合共享任务的场景。 - 使用
Callable
和Future
:Callable
可以返回结果并抛出异常,适合需要结果的任务,通过Future
获取任务结果。 - 使用线程池:通过
ExecutorService
创建线程池,复用线程,提高性能,适合高并发场景。
在实际开发中,线程池是推荐的方式,因为它不仅可以有效管理线程,还能提高程序的性能和可扩展性。
相关文章:

Java 创建线程的方式有哪几种
在 Java 中,创建线程的方式有四种,分别是:继承 Thread 类、实现 Runnable 接口、使用 Callable 和 Future、使用线程池。以下是详细的解释和通俗的举例: 1. 继承 Thread 类 通过继承 Thread 类并重写 run() 方法来创建线程。 步…...

计算机的错误计算(一百八十七)
摘要 用大模型计算 sin(123.456789). 其自变量为弧度。结果保留16位有效数字。第一个大模型是数学大模型。先是只分析,不计算;后经提醒,才给出结果,但是是错误结果。第二个大模型,直接给出了Python代码与结果…...

12. 最大括号深度
题目描述 现有一字符串仅由"(",")", "{","}", "[", "]"六种括号组成。若字符串满足以下条件之一, 则为无效字符串:任一类型的左右括号数量不相等 存在未按正确顺序(先左后右)闭合的括号输出…...

进程与线程以及如何查看
长期补充,建议关注收藏! 定义 特性进程线程定义程序执行的基本单位执行中的最小单位资源拥有独立的内存空间和资源共享进程的资源开销创建和销毁的开销较大创建和销毁的开销较小执行单位进程中可以有多个线程线程是执行单元,必须依赖于进程并…...

BlueLM:以2.6万亿token铸就7B参数超大规模语言模型
一、介绍 BlueLM 是由 vivo AI 全球研究院自主研发的大规模预训练语言模型,本次发布包含 7B 基础 (base) 模型和 7B 对话 (chat) 模型,同时我们开源了支持 32K 的长文本基础 (base) 模型和对话 (chat) 模型。 更大量的优质数据 :高质量语料…...

Webpack学习笔记(4)
1.缓存 可以通过命中缓存降低网络流量,是网站加站速度更快。 然而在部署新版本时,不更改资源的文件名,浏览器可能认为你没有更新,所以会使用缓存版本。 由于缓存存在,获取新的代码成为问题。 接下来将配置webpack使…...

28、论文阅读:基于像素分布重映射和多先验Retinex变分模型的水下图像增强
A Pixel Distribution Remapping and Multi-Prior Retinex Variational Model for Underwater Image Enhancement 摘要介绍相关工作基于模型的水下图像增强方法:无模型水下图像增强方法:基于深度学习的水下图像增强方法: 论文方法概述像素分布…...

5.interview-self-introduction
1.保证电话面试来的时候,可以接听,保持电话通常 interviews will be arranged recently.please keep your phone line open and make sure you can answer th call when the phone interview comes. speak loudly and slow down your speaking voice &a…...

高性能MySQL-查询性能优化
查询性能优化 1、为什么查询这么慢2、慢查询基础:优化数据访问2.1 是否向数据库请求了不需要的数据2.2 MySQL是否存在扫描额外的记录 3、重构查询方式3.1 一个复杂查询还是多个简单查询3.2 切分查询3.3 分解联接查询 4、查询执行的基础4.1 MySQL的客户端/服务器通信…...

如何有效修复ffmpeg.dll错误:一站式解决方案指南
当您遇到提示“ffmpeg.dll文件丢失”的错误时,这可能导致相关的应用程序无法启动或运行异常。本文将详细介绍如何有效地解决ffmpeg.dll文件丢失的问题,确保您的应用程序能够恢复正常运行。 ffmpeg.dll是什么?有哪些功能? ffmpeg.…...

8086汇编(16位汇编)学习笔记00.DEBUG命令使用解析及范例大全
8086汇编(16位汇编)学习笔记00.DEBUG命令使用解析及范例大全-C/C基础-断点社区-专业的老牌游戏安全技术交流社区 - BpSend.net[md]启动 Debug,它是可用于测试和调试 MS-DOS 可执行文件的程序。 Debug [[drive:][path] filename [parameters]] 参数 [drive:…...

查看mysql的冷数据配置比例
查看mysql的冷数据配置比例 -- 真正的LRU链表,会被拆分为两个部分,一部分是热数据,一部分是冷数据,这个冷热数据的比例是由innodb_old_blocks_pct参数控制的,它默认是37,也就是说冷数据占比37%。 show GLO…...

【Java基础面试题028】Java中的hashCode和equals方法,与==操作符有什么区别?
回答重点 hashcode、equals 和 都是Java中用于比较对象的三种方式,但是它们的用途和实现还是有挺大区别的。 hashcode用于散列存储结构中确定对象的存储位置。可用于快速比较两个对象是否不同,因为如果它们的哈希码不同,那么它们肯定不相等…...

在C#中测试比较目录的不同方法以查看它们有哪些共同的文件
C# 中的示例“比较目录以查看它们有哪些共同的文件”使用Directory.GetFiles获取两个目录中的文件。它对文件进行排序,并比较两个排序后的列表以查看哪些文件位于第一个目录中、第二个目录中或两个目录中。有关其工作原理的详细信息,请参阅该示例。 Kur…...

harbor离线安装 配置https 全程记录
1. 下载harbor最新版本 下载网址: 找最新的版本: https://github.com/goharbor/harbor/releases/download/v2.11.2/harbor-offline-installer-v2.11.2.tgz 这里我直接使用迅雷下载, 然后上传 1.1解压 sudo tar -xf harbor-offline-installer-v2.11.2.tgz -C /opt/ 2. 配置Harb…...

C++简明教程(文章要求学过一点C语言)(5)
在开始之前必须阅读这个文章 https://blog.csdn.net/weixin_45100742/article/details/135152562 这篇文章完全是对C语言的补课,如果C语言学的好,可跳过。 变量、数据类型与运算符 在 C 编程中,理解变量、数据类型和运算符是构建程序的基石…...

Halcon单相机+机器人=眼在手上#标定心得
首先,这个标定板肯定是放在我们要作业的工作台上的 目的 **1,得到标定物(工作台)与机器人底座之间的pose转换关系。2,得到相机与机器人末端tool的的转换关系。 两个不确定的定量 1,标定板与机器人底座b…...

【hackmyvm】Diophante 靶场
1. 基本信息^toc 这里写目录标题 1. 基本信息^toc2. 信息收集2.1. 端口扫描2.2. 目录扫描2.3. knock 3. WordPress利用3.1. wpscan扫描3.2. smtp上传后门 4. 提权4.1. 提权leonard用户4.2. LD劫持提权root 靶机链接 https://hackmyvm.eu/machines/machine.php?vmDiophante 作者…...

C++类的继承关系中什么时候要用到上行转换和下行转换
一、C类继承关系中的上行转换 1. 多态性实现 在C中,上行转换(将派生类转换为基类)是实现多态性的关键。例如,当有一个基类Animal,以及派生类Dog和Cat。如果有一个函数接受Animal类型的参数,我们可以将Dog或…...

Ubuntu 22.04永久保存路由
在 Ubuntu 22.04 上,可以按照以下方式配置让流量访问 172.19.201.207 走指定的路由。 1. 临时添加路由 临时路由规则只在当前系统会话中有效,重启后会丢失。 添加路由规则 运行以下命令: sudo ip route add 172.19.201.207 via 192.168.2…...

数据结构十大排序之(冒泡,快排,并归)
接上期: 数据结十大排序之(选排,希尔,插排,堆排)-CSDN博客 前言: 在计算机科学中,排序算法是最基础且最重要的算法之一。无论是大规模数据处理还是日常的小型程序开发,…...

OpenFeign源码
openfeign是通过FeignClientFactoryBean生成动态代理对象的方式实现http客户端无感调用,可以做到像定义接口一样写http客户端调用代码。 配置Feign接口后,我们通常会在SpringBoot项目启动类上标记EnableFeignClients,这个是生成动态代理对象的…...

sql server索引优化语句
第一步 建一个测试表 --create table TestUsers --( -- Id int primary key identity(1,1), -- Username varchar(30) not null, -- Password varchar(10) not null, -- CreateDateTime datetime not null --)第二步 插入100w数据 大概1分钟执行时间 ----插入数据…...

深度学习之超分辨率算法——SRGAN
更新版本 实现了生成对抗网络在超分辨率上的使用 更新了损失函数,增加先验函数 SRresnet实现 import torch import torchvision from torch import nnclass ConvBlock(nn.Module):def __init__(self, kernel_size3, stride1, n_inchannels64):super(ConvBlock…...

16.2、网络安全风险评估技术与攻击
目录 网络安全风险评估技术方法与工具 网络安全风险评估技术方法与工具 资产信息收集,可以通过调查表的形式把我们各类的资产信息进行一个统计和收集,掌握被评估对象的重要资产分布,进而分析这些资产关联的业务面临的安全威胁以及存在的安全…...

【项目管理】GDB调试
gdb(GNU Debugger) 是 Linux 和嵌入式开发中最常用的调试工具之一,可以用来调试 C/C 程序、排查崩溃、分析程序流程等。在嵌入式开发中,gdb 还可以通过远程调试(gdbserver)调试目标设备上的程序。 这篇文章…...

ChatGPT生成接口测试用例(一)
用ChatGPT做软件测试 接口测试在软件开发生命周期中扮演着至关重要的角色,有助于验证不同模块之间的交互是否正确。若协议消息被恶意修改,系统是否能够恰当处理,以确保系统的功能正常运行,不会出现宕机或者安全问题。 5.1 ChatGP…...

2024 年 IA 技术大爆发深度解析
摘要: 本文旨在深入剖析 2024 年 IA 技术大爆发所引发的多方面反响。通过对产业变革、经济影响、就业市场、社会影响、政策与监管以及未来展望等维度的探讨,揭示 IA 技术在这一关键时期对全球各个层面带来的深刻变革与挑战,并提出相应的思考与…...

如何进行js后台框架搭建(树形菜单,面包屑,全屏功能,刷新功能,监听页面刷新功能)
框架功能是后台高亮不可缺少的功能,基本上所有的后台都需要框架功能,下面是我制作好的一个效果图 下面是我的框架里面功能的具体讲解,还有完整的代码示例 1.声明的变量 // 声明一个用于判断个人信息显示变量 let myes 0; // 声明一个用于切…...

多目标优化常用方法:pareto最优解
生产实际中的许多优化问题大都是多目标问题,举个例子:我们想换一份工资高、压力小、离家近的新工作,这里工资高、压力小、离家近就是我们的目标,显然这是一个多目标问题,那我们肯定想找到这三个目标同时最优的工作&…...