Java实现多线程的三种方式

Java 有三种方式实现多线程,继承 Thread 类、实现 Runnable 接口、实现 Callable 接口。还有匿名内部类方式,Lambda 表达式方式简化开发。

1、Thread

Thread 创建线程方式:创建线程类

  • start() 方法底层其实是给 CPU 注册当前线程,并且触发 run() 方法执行

  • 线程的启动必须调用 start() 方法,如果线程直接调用 run() 方法,相当于变成了普通类的执行,此时主线程将只有执行该线程

  • 建议线程先创建子线程,主线程的任务放在之后,否则主线程(main)永远是先执行完

Thread 构造器:

  • public Thread()

  • public Thread(String name)

public class p1 {public static void main(String[] args) {// 创建线程类方式Thread t1 = new MyThread();t1.start();}
}
class MyThread extends Thread{@Overridepublic void run() {for(int i = 0 ; i < 100 ; i++ ) {// 子线程输出System.out.println(Thread.currentThread().getName() + "->" + i);}}
}

继承 Thread 类的优缺点:

  • 优点:编码简单

  • 缺点:线程类已经继承了 Thread 类无法继承其他类了,功能不能通过继承拓展(单继承的局限性)

2、Runnable

Runnable 创建线程方式:创建线程类

Thread 的构造器:

  • public Thread(Runnable target)

  • public Thread(Runnable target, String name)

public class p2 {public static void main(String[] args) {Runnable target = new MyRunnable();Thread t1 = new Thread(target,"Runnable线程");t1.start();Thread t2 = new Thread(target);//Thread-0}
}public class MyRunnable implements Runnable{@Overridepublic void run() {for(int i = 0 ; i < 10 ; i++ ){System.out.println(Thread.currentThread().getName() + "->" + i);}}
}

Thread 类本身也是实现了 Runnable 接口,Thread 类中持有 Runnable 的属性,执行线程 run 方法底层是调用 Runnable#run:

 public class Thread implements Runnable {private Runnable target;public void run() {if (target != null) {// 底层调用的是 Runnable 的 run 方法target.run();}}}

Runnable 方式的优缺点:

  • 缺点:代码复杂一点。

  • 优点

    • 线程任务类只是实现了 Runnable 接口,可以继续继承其他类,避免了单继承的局限性

    • 同一个线程任务对象可以被包装成多个线程对象

    • 适合多个多个线程去共享同一个资源

    • 实现解耦操作,线程任务代码可以被多个线程共享,线程任务代码和线程独立

    • 线程池可以放入实现 Runnable 或 Callable 线程任务对象

3、Callable

实现 Callable 接口:

  1. 定义一个线程任务类实现 Callable 接口,申明线程执行的结果类型

  2. 重写线程任务类的 call 方法,这个方法可以直接返回执行的结果

  3. 创建一个 Callable 的线程任务对象

  4. 把 Callable 的线程任务对象包装成一个未来任务对象

  5. 把未来任务对象包装成线程对象

  6. 调用线程的 start() 方法启动线程

public FutureTask(Callable<V> callable):未来任务对象,在线程执行完后得到线程的执行结果

  • FutureTask 就是 Runnable 对象,因为 Thread 类只能执行 Runnable 实例的任务对象,所以把 Callable 包装成未来任务对象

public V get():同步等待 task 执行完毕的结果,如果在线程中获取另一个线程执行结果,会阻塞等待,用于线程同步

  • get() 线程会阻塞等待任务执行完成

  • run() 执行完后会把结果设置到 FutureTask 的一个成员变量,get() 线程可以获取到该变量的值

public class p3 {public static void main(String[] args) {Callable<String> call = new MyCallable();FutureTask<String> task = new FutureTask<>(call);Thread t1 = new Thread(task);t1.start();try {// 获取call方法返回的结果(正常/异常结果)String s = task.get(); System.out.println(s);}  catch (Exception e) {e.printStackTrace();}}public class MyCallable implements Callable<String> {@Overridepublic String call() throws Exception {return Thread.currentThread().getName() + "->" + "MyCallable String";}
}

优缺点:

  • 优点:同 Runnable,并且能得到线程执行的结果

  • 缺点:编码复杂

4、匿名内部类方式、Lambda 表达式方式
public class p1 {public static void main(String[] args) {// 匿名内部类方式Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("t1 线程执行中");}});t1.start();// Lambda 表达式创建匿名内部类的线程对象Thread t2= new Thread(() -> {System.out.println("t2 线程执行中");});t2.start();}
}    

使用匿名内部类的方式可以方便地定义并实例化线程对象,并实现线程的执行逻辑。它对于一些简单的线程任务可以简洁地表达,但对于复杂的线程逻辑,建议使用具名的内部类或者单独定义一个类来实现Runnable接口

使用 lambda 表达式代替了匿名内部类,使得代码更加简洁。适用于只包含一个抽象方法的接口,例如 Runnable 接口和 Callable 接口。对于其他接口,如果包含多个抽象方法,就无法使用 lambda 表达式来创建匿名内部类。

借鉴:https://github.com/Seazean/JavaNote/blob/main/Prog.md

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

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

相关文章

关于IDEA中maven的作用以及如何配置MAVEN

关于IDEA中maven的作用以及如何配置MAVEN 1、Maven是什么2、Idea中对于Maven的配置3、下载依赖时&#xff0c;Idea下方的显示3.1、Maven中央仓库的下载显示界面3.2、阿里云仓库的下载显示界面 4、Maven在Idea中的使用4.1、clean4.2、validate4.3、compile4.4、test&#xff08;…

智能优化算法应用:基于人工蜂群算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于人工蜂群算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于人工蜂群算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.人工蜂群算法4.实验参数设定5.算法结果6.…

java智能异常处理

标题&#xff1a;优雅处理异常&#xff1a;Java智能异常处理的最佳实践 摘要&#xff1a;在软件开发中&#xff0c;异常处理是一项至关重要的任务。本文将介绍Java中的智能异常处理技术&#xff0c;通过合理的异常处理规范和最佳实践&#xff0c;帮助开发者优雅地处理异常情况…

从零构建属于自己的GPT系列5:模型部署1(文本生成函数解读、模型本地化部署、文本生成文本网页展示、代码逐行解读)

&#x1f6a9;&#x1f6a9;&#x1f6a9;Hugging Face 实战系列 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在PyCharm中进行 本篇文章配套的代码资源已经上传 从零构建属于自己的GPT系列1&#xff1a;数据预处理 从零构建属于自己的GPT系列2&#xff1a;模型训…

2023年国赛高教杯数学建模A题定日镜场的优化设计解题全过程文档及程序

2023年国赛高教杯数学建模 A题 定日镜场的优化设计 原题再现 构建以新能源为主体的新型电力系统&#xff0c;是我国实现“碳达峰”“碳中和”目标的一项重要措施。塔式太阳能光热发电是一种低碳环保的新型清洁能源技术[1]。   定日镜是塔式太阳能光热发电站&#xff08;以下…

ES6-import后是否有{}的区别

在ES6中&#xff0c;import语句用于导入其他模块中的变量、函数、类等。在使用import语句时&#xff0c;可以选择是否使用花括号{}来包裹导入的内容&#xff0c;这会影响导入的内容的使用方式。 1.使用花括号{}&#xff1a; 当使用花括号{}时&#xff0c;表示只导入指定的变量…

【Fastadmin】根据Fieldlist键值组件做一个等级配置的完整示例

目录 1.效果展示&#xff1a; ​编辑 2.建表&#xff1a; 3.html页面 4.controller控制器 5.js 6.model 1.效果展示&#xff1a; 2.建表&#xff1a; 表名&#xff1a;fa_xxfb_config /*Navicat Premium Data TransferSource Server : rootSource Server Type …

深入Docker命令行:探索常用命令和实用技巧

Docker命令行界面是每个容器开发者的得力工具。在这篇文章中&#xff0c;将深入探讨一系列常用的Docker命令&#xff0c;以及一些实用技巧&#xff0c;通过更丰富的示例代码&#xff0c;帮助大家更全面地理解和运用Docker命令行工具。 1. Docker基本命令 1.1 镜像操作 深入了…

用 CSS 写一个渐变色边框的输入框

Using_CSS_gradients MDN 多渐变色输入框&#xff0c;群友问了下&#xff0c;就试着写了下&#xff0c;看了看 css 渐变色 MDN 文档&#xff0c;其实很简单&#xff0c;代码记录下&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta ch…

使用FFMPEG转码,转单声道,转标准WAV,转PCM

本文为使用FFMPEG命令行的方式处理音频&#xff0c;来获取想要得到的音频文件。 零、使用命令行查看编码封装信息 格式&#xff1a;ffprobe.exe -show_format inputfile 例子&#xff1a;ffprobe.exe -show_format .\stereo_44_16bit.wav 运行结果为下图&#xff1a; 如图可…

C# Channel实现线程间通信

C# Channel实现线程间通信 同步方式实现&#xff1a; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Channels; using System.Threading.T…

【JavaFX】实现计算器小程序

下面是一个简单的JavaFX计算器示例: import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.…

西南科技大学数字电子技术实验四(基本触发器逻辑功能测试及FPGA的实现)预习报告

一、计算/设计过程 说明:本实验是验证性实验,计算预测验证结果。是设计性实验一定要从系统指标计算出元件参数过程,越详细越好。用公式输入法完成相关公式内容,不得贴手写图片。(注意:从抽象公式直接得出结果,不得分,页数可根据内容调整) (1)D触发器 特征方程: Q…

往adobe illustrator中添加latex字体

找到如下字体所在路径 /path/to/miktex/type1\public\amsfonts\cm然后copy相应的字体文件 cmmi10.pfb将相应的pfb文件复制到Adobe illustrator字体文件夹: /path/to/illustrator/Support Files/Required/Fonts然后重启即可。

ChatGPT/GPT4应用:文本、论文、编程、绘图等,提高工作效率及科研项目开发能力

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

排序-选择排序与堆排序

文章目录 一、选择排序二、堆排序三、时间复杂度四、稳定性 一、选择排序 思想&#xff1a; 将数组第一个元素作为min&#xff0c;然后进行遍历与其他元素对比&#xff0c;找到比min小的数就进行交换&#xff0c;直到最后一个元素就停止&#xff0c;然后再将第二个元素min&…

【单调栈】【二分查找】LeetCode: 2454.下一个更大元素 IV

作者推荐 【动态规划】【广度优先】LeetCode2258:逃离火灾 本文涉及的基础知识点 二分查找算法合集 单调栈 题目 给你一个下标从 0 开始的非负整数数组 nums 。对于 nums 中每一个整数&#xff0c;你必须找到对应元素的 第二大 整数。 如果 nums[j] 满足以下条件&#xff…

音视频技术开发周刊 | 323

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 Meta牵头组建开源「AI复仇者联盟」&#xff0c;AMD等盟友800亿美元力战OpenAI英伟达 超过50家科技大厂名校和机构&#xff0c;共同成立了全新的人工智能联盟。以开源为旗号…

RocketMQ的架构是什么样的❓

RocketMQ&#xff0c;作为一款强大的分布式消息中间件&#xff0c;广泛应用于各种大规模分布式系统中&#xff0c;为异步消息通信提供了可靠的解决方案。本文将深入探讨RocketMQ的核心组件&#xff0c;包括Producer、Broker、Consumer和NameServer&#xff0c;以及它们在整个架…

高中物理电学总结之稳恒电流篇

高中物理电学总结之稳恒电流篇 电流电流的定义对电流的微观分析 电阻欧姆定律电阻的串并联电阻定律 电源的电动势电源电动势 闭合电路欧姆定律闭合电路闭合电路欧姆定律 电流做功与焦耳定律电流做功电功率焦耳定律电源效率 电表改装 电流 电流的定义 电解质溶液中的自由电荷是…