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

Java 创建线程的方式有哪几种

在 Java 中,创建线程的方式有四种,分别是:继承 Thread 类、实现 Runnable 接口、使用 CallableFuture、使用线程池。以下是详细的解释和通俗的举例:


1. 继承 Thread

通过继承 Thread 类并重写 run() 方法来创建线程。

步骤:

  1. 创建一个 Thread 类的子类,重写 run() 方法,定义线程执行的任务。
  2. 创建该子类的实例,并调用 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 对象来创建线程。

步骤:

  1. 创建一个实现了 Runnable 接口的类,并重写 run() 方法。
  2. 创建 Runnable 实例,将其传递给 Thread 构造方法。
  3. 调用 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. 使用 CallableFuture 接口

Callable 接口与 Runnable 接口类似,但它能够返回结果,并且可以抛出异常。通过 ExecutorService 来管理线程池,并提交 Callable 任务获取 Future 对象,以便在未来某个时刻获取任务的计算结果。

步骤:

  1. 创建实现 Callable 接口的类,重写 call() 方法,定义线程任务,并返回结果。
  2. 使用 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 来创建和管理线程池,并提交任务。线程池允许线程复用,避免了频繁创建和销毁线程的开销。

步骤:

  1. 使用 ExecutorService 创建线程池,通常使用 Executors 类来创建。
  2. 提交任务到线程池执行,可以提交 RunnableCallable 任务。

代码示例:

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() 方法用于关闭线程池。

优点:

  • 可以复用线程,避免了每次创建新线程的开销。
  • 线程池可以根据系统资源动态调整线程数量,适用于高并发场景。

缺点:

  • 需要管理线程池的生命周期,避免线程池资源泄漏。

总结

  1. 继承 Thread:直接继承并重写 run() 方法,适合简单场景,但无法继承其他类。
  2. 实现 Runnable 接口:实现 Runnable 接口的类并重写 run() 方法,适合共享任务的场景。
  3. 使用 CallableFutureCallable 可以返回结果并抛出异常,适合需要结果的任务,通过 Future 获取任务结果。
  4. 使用线程池:通过 ExecutorService 创建线程池,复用线程,提高性能,适合高并发场景。

在实际开发中,线程池是推荐的方式,因为它不仅可以有效管理线程,还能提高程序的性能和可扩展性。

相关文章:

Java 创建线程的方式有哪几种

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

计算机的错误计算(一百八十七)

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

12. 最大括号深度

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

进程与线程以及如何查看

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

BlueLM:以2.6万亿token铸就7B参数超大规模语言模型

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

Webpack学习笔记(4)

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

28、论文阅读:基于像素分布重映射和多先验Retinex变分模型的水下图像增强

A Pixel Distribution Remapping and Multi-Prior Retinex Variational Model for Underwater Image Enhancement 摘要介绍相关工作基于模型的水下图像增强方法&#xff1a;无模型水下图像增强方法&#xff1a;基于深度学习的水下图像增强方法&#xff1a; 论文方法概述像素分布…...

5.interview-self-introduction

1.保证电话面试来的时候&#xff0c;可以接听&#xff0c;保持电话通常 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、慢查询基础&#xff1a;优化数据访问2.1 是否向数据库请求了不需要的数据2.2 MySQL是否存在扫描额外的记录 3、重构查询方式3.1 一个复杂查询还是多个简单查询3.2 切分查询3.3 分解联接查询 4、查询执行的基础4.1 MySQL的客户端/服务器通信…...

如何有效修复ffmpeg.dll错误:一站式解决方案指南

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

8086汇编(16位汇编)学习笔记00.DEBUG命令使用解析及范例大全

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

查看mysql的冷数据配置比例

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

【Java基础面试题028】Java中的hashCode和equals方法,与==操作符有什么区别?

回答重点 hashcode、equals 和 都是Java中用于比较对象的三种方式&#xff0c;但是它们的用途和实现还是有挺大区别的。 hashcode用于散列存储结构中确定对象的存储位置。可用于快速比较两个对象是否不同&#xff0c;因为如果它们的哈希码不同&#xff0c;那么它们肯定不相等…...

在C#中测试比较目录的不同方法以查看它们有哪些共同的文件

C# 中的示例“比较目录以查看它们有哪些共同的文件”使用Directory.GetFiles获取两个目录中的文件。它对文件进行排序&#xff0c;并比较两个排序后的列表以查看哪些文件位于第一个目录中、第二个目录中或两个目录中。有关其工作原理的详细信息&#xff0c;请参阅该示例。 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语言的补课&#xff0c;如果C语言学的好&#xff0c;可跳过。 变量、数据类型与运算符 在 C 编程中&#xff0c;理解变量、数据类型和运算符是构建程序的基石…...

Halcon单相机+机器人=眼在手上#标定心得

首先&#xff0c;这个标定板肯定是放在我们要作业的工作台上的 目的 **1&#xff0c;得到标定物&#xff08;工作台&#xff09;与机器人底座之间的pose转换关系。2&#xff0c;得到相机与机器人末端tool的的转换关系。 两个不确定的定量 1&#xff0c;标定板与机器人底座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中&#xff0c;上行转换&#xff08;将派生类转换为基类&#xff09;是实现多态性的关键。例如&#xff0c;当有一个基类Animal&#xff0c;以及派生类Dog和Cat。如果有一个函数接受Animal类型的参数&#xff0c;我们可以将Dog或…...

Ubuntu 22.04永久保存路由

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

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践

在 Kubernetes 集群中&#xff0c;如何在保障应用高可用的同时有效地管理资源&#xff0c;一直是运维人员和开发者关注的重点。随着微服务架构的普及&#xff0c;集群内各个服务的负载波动日趋明显&#xff0c;传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...

Java并发编程实战 Day 11:并发设计模式

【Java并发编程实战 Day 11】并发设计模式 开篇 这是"Java并发编程实战"系列的第11天&#xff0c;今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案&#xff0c;它们不仅提供了优雅的设计思路&#xff0c;还能显著提升系统的性能…...

Yii2项目自动向GitLab上报Bug

Yii2 项目自动上报Bug 原理 yii2在程序报错时, 会执行指定action, 通过重写ErrorAction, 实现Bug自动提交至GitLab的issue 步骤 配置SiteController中的actions方法 public function actions(){return [error > [class > app\helpers\web\ErrorAction,],];}重写Error…...

CMS内容管理系统的设计与实现:多站点模式的实现

在一套内容管理系统中&#xff0c;其实有很多站点&#xff0c;比如企业门户网站&#xff0c;产品手册&#xff0c;知识帮助手册等&#xff0c;因此会需要多个站点&#xff0c;甚至PC、mobile、ipad各有一个站点。 每个站点关联的有站点所在目录及所属的域名。 一、站点表设计…...

【阅读笔记】MemOS: 大语言模型内存增强生成操作系统

核心速览 研究背景 ​​研究问题​​&#xff1a;这篇文章要解决的问题是当前大型语言模型&#xff08;LLMs&#xff09;在处理内存方面的局限性。LLMs虽然在语言感知和生成方面表现出色&#xff0c;但缺乏统一的、结构化的内存架构。现有的方法如检索增强生成&#xff08;RA…...