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

【多线程初阶篇 ²】创建线程的方式

目录

二、多线程代码

1.继承Thread类

2.实现Runnable接口

 3.匿名内部类

3.1 创建Thread⼦类对象

3.2 创建Runnable⼦类对象

4.lambda表达式(推荐)

 小结:

🔥面试题:Java中创建线程都有哪些写法


二、多线程代码

1.继承Thread类

package thread;class MyThread extends Thread {@Overridepublic void run() {//这里写的代码就是该线程要完成的工作while (true) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}public class Demo1 {public static void main(String[] args) throws InterruptedException {Thread t = new MyThread();//t.start();//没有创建出新的线程,就是在主线程中执行run中的循环打印(就是单线程了,串行执行)t.run();while (true) {System.out.println("hello main");t.sleep(1000);}}
}
  • 上述代码中其实有两个线程,一个t线程,一个main线程(主线程:JVM进程启动的时候,自己创建的线程)
  • 重写Thread方法中的run方法:描述线程需要完成的工作
    • 只是定义好,把这个方法的调用交给系统/其他的库/其他框架调用,(回调函数)
  • sleep方法:让当前线程主动进入“阻塞”状态,主动放弃在CPU上的执行,时间到了,才会解除,重新被调度到CPU上执行
  • start方法:调用操作系统提供创建线程的API,在内核中创建对应的PCB,并且把PCB加入到链表中,进一步的系统调度到这个线程之后,就会执行上述run方法的逻辑
  • Q1如果开发中,发现你负责的服务器程序,消耗CPU资源超出预期,你如何排查?
    • 首先确认是哪个线程消耗的CPU比较高
    • 进一步排查,线程中是否有类似的“非常快速的”循环
    • 确认是否这里的循环一个这么快
      • 应该的话就可以升级更好的CPU
      • 如果不应该,说明需要在循环中引入一些等待操作
  • 上述代码结果顺序是不确定的:
    • 多线程的调度是无序的,即抢占式执行:任何一个线程 在执行任何一个代码的时候,都可能被其他线程抢占CPU资源

2.实现Runnable接口

package thread;class MyRunnable implements Runnable {@Overridepublic void run() {while (true) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}public class Demo2 {public static void main(String[] args) {Thread t = new Thread(new MyRunnable());t.start();while (true) {System.out.println("hello main");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
  • Runnable的作用:是描述一个“任务”,表示“可执行的”
  • 和继承Thread类创建线程比较
    • 一是Thread自己记录要干啥
    • 二是Runnable记录要干啥,Thread负责执行
      好处:解耦合,把任务和线程拆分开,把这样的任务给其他地方执行

 3.匿名内部类

3.1 创建Thread⼦类对象
package thread;public class Demo3 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread() {@Overridepublic void run() {while(true) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}};t.start();while (true) {System.out.println("hello main");Thread.sleep(1000);}}
}
  • 过程
    • 创建一个Thread子类
    • 同时创建一个该子类的实例
      但是对于匿名内部类来说,只能创建这一个实例,因为拿不到名字
    • 子类内部重新父类的run方法
  • 好处:简单

3.2 创建Runnable⼦类对象
package thread;public class Demo4 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(new Runnable() {@Overridepublic void run() {while (true) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}});t.start();while (true) {System.out.println("hello main");Thread.sleep(1000);}}
}
  • 过程:和3.1代码一样
  • 区别:此处的匿名内部类只是针对Runnable,和Thread没有关系
    只是把Runnable的实例,作为参数传入Thread的构造方法中
  • Q1为什么在main方法中处理sleep异常有两种选择,而线程run中的sleep方法只有一种
    • main方法可以
      • throws
      • try catch
    • 线程中的run方法
      • 只能try catch
    • 因为父类run中没有抛出异常,由于重写要求方法签名是一样的的,也无法抛出异常
      throws其实是方法签名的一部分(方法名字+方法的参数列表【不包含返回值和pubic/private】+声明抛出的异常)

4.lambda表达式(推荐

package thread;public class Demo5 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {while (true) {System.out.println("hello thread");try {Thread.sleep(10000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();while (true) {System.out.println("hello main");Thread.sleep(1000);}}
}
  • 本质就是一个”匿名函数“,一次性函数,用完就丢

 小结:

  • 5种方法都是要把线程的任务内容表示出来
  • 通过Thread的start来创建/启动系统中的线程
    Thread对象和操作系统中的线程是一一对应的关系

🔥面试题:Java中创建线程都有哪些写法

  • 继承Thread类
  • 实现Runnable接口
  • 匿名内部类
    • 创建Thread子类
    • 创建Runnable子类
  • lambda表达式
  • 实现Callable接口(TODO)
  • 使用线程池(TODO)

相关文章:

【多线程初阶篇 ²】创建线程的方式

目录 二、多线程代码 1.继承Thread类 2.实现Runnable接口 3.匿名内部类 3.1 创建Thread⼦类对象 3.2 创建Runnable⼦类对象 4.lambda表达式(推荐) 小结: 🔥面试题:Java中创建线程都有哪些写法 二、多线程代码 …...

纵览!报表控件 Stimulsoft Reports、Dashboards 和 Forms 2025.1 新版本发布!

Stimulsoft 2025.1 新版发布,旨在增强您创建报告、仪表板和 PDF 表单的体验!此最新版本为您带来了许多改进和新功能,使数据处理更加高效和用户友好。亮点包括对 .NET 9 的支持、Microsoft Analysis Services 的新数据适配器、发布向导中适用于…...

游戏引擎学习第75天

仓库:https://gitee.com/mrxiao_com/2d_game_2 Blackboard: 处理楼梯通行 为了实现楼梯的平滑过渡和角色的移动控制,需要对楼梯区域的碰撞与玩家的运动方式进行优化。具体的处理方式和遇到的问题如下: 楼梯区域的过渡: 在三维空间中&#x…...

Java 23 集合框架详解:Set 接口及实现类(HashSet、TreeSet、LinkedHashSet)

📚 Java 23 集合框架详解:Set 接口及实现类(HashSet、TreeSet、LinkedHashSet) 📖 概述 Set 是 Java 集合框架中用于存储 无序、不重复元素 的接口。它的实现类包括 HashSet、TreeSet 和 LinkedHashSet,它…...

ARMv8架构 CortexR52+ 内核 coresight_soc400介绍

前言:笔者在工作中接触到了一款多核芯片,其采用的处理器为CortexR52,使用的架构为ARMv8,我通过CoreSight SOC-400组件完成了对该芯片烧录代码的开发。这里芯片型号就不透露了,本文仅介绍我自己从ARM官网上提供的R52核等…...

1.Python浅过(语法基础)

1.简介 Python是一种面向对象的解释型高级编程语言,是强类型的动态脚本语言。 解释型语言跨平台性比编译型语言(如c语言)好。 print("hello world")2.Bug,Debug 多看,多思考,多尝试、查资料、记录 3.prin…...

ioremap_nocache函数

ioremap_nocache 是 Linux 内核中用于将物理地址映射到内核虚拟地址空间的函数,特别是用于 I/O 内存映射,并且禁用缓存。 一、基本语法 void __iomem *ioremap_nocache(phys_addr_t phys_addr, size_t size); 二、基本功能 将物理内存地址映射到内核虚拟…...

【235. 二叉搜索树的最近公共祖先 中等】

题目: 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一…...

构建智能企业:中关村科金大模型企业知识库的技术解析与应用

在数字化转型的浪潮中,企业对智能化知识管理的需求日益增长。知识作为企业的核心资产,其高效管理和应用对于提升企业运营效率和决策质量至关重要。中关村科金大模型企业知识库凭借其强大的技术架构和广泛的应用场景,成为构建智能企业的重要工…...

C++进阶——用Hash封装unordered_map和unordered_set

目录 前言 源码怎么说 为什么要兼容? 兼容的具体做法? 为什么要把Key转为整数(HashFcn)? 模拟实现 一、建立框架 二、迭代器 运算符重载 迭代器兼容大法 三、[ ]重载 四、实现不能修改key 实现及测试代码 …...

b612相机 13.5.5解锁会员hook

工具 lspatch(点击选最新版本下载) shizuku(点击选最新版本下载) SimpleHook(点击选最新版本下载) b612(自行百度下载) 效果图 教程 [{"packageName":"com.camp…...

iOS - 弱引用表(Weak Reference Table)

1. 基本数据结构 // 弱引用表的基本结构 struct weak_table_t {weak_entry_t *weak_entries; // 保存所有的弱引用对象size_t num_entries; // 当前存储的弱引用数量uintptr_t mask; // 哈希表大小掩码uintptr_t max_hash_displacement; /…...

C#语言的网络编程

C#语言的网络编程 引言 随着互联网的飞速发展,网络编程成为了软件开发中的一个重要领域。C#语言作为一种现代编程语言,凭借其丰富的类库、良好的可读性和强大的功能,广泛应用于开发各种网络应用程序。无论是Windows应用、Web应用还是云服务…...

【操作系统】课程 4调度与死锁 同步测练 章节测验

4.1知识点导图 处理机调度与死锁相关内容的文字整理: 基本准则 资源利用率:使系统中的处理机和其他所有资源都尽可能地保持忙碌状态。系统吞吐量:单位时间内系统所完成的作业数。公平性:使各进程都获得合理的CPU时间,而…...

如何查看已经安装的python版本和相关路径信息

如何查看已经安装的python版本和相关路径信息 本文目录: 一、通过命令行模式查询 1、通过命令where python 2、通过命令print(sys.executable) 二、在 Anaconda Navigator 中 三、只安装python的环境下 一、通过命令行模式查询 同时按windowR键,输入cmd&#x…...

设计模式-结构型-适配器模式

在软件开发中,随着系统的不断扩展和模块的不断增加,往往会遇到不同模块之间接口不兼容的情况。此时,如果我们能通过某种方式将一个接口转化为另一个接口,那么开发工作将变得更加灵活和高效。适配器模式(Adapter Patter…...

鸿蒙操作系统(HarmonyOS)

鸿蒙操作系统(HarmonyOS)是华为公司推出的一款面向未来、面向全场景的分布式操作系统。它旨在为用户提供一个更加智能、便捷和安全的操作环境,支持多种终端设备之间的无缝协作。在鸿蒙应用开发中,ArkUI作为官方推荐的用户界面开发…...

基于海思soc的智能产品开发(camera sensor的两种接口)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 对于嵌入式开发设备来说,除了图像显示,图像输入也是很重要的一部分。说到图像输入,就不得不提到camera。目前ca…...

解密LLM结构化输出:代码示例与原理分析

解密LLM结构化输出:代码示例与原理分析 一、LLM结构化输出概述 1. 结构化输出的定义与优势 结构化输出指的是语言模型(LLM)生成的遵循特定格式(如JSON、XML)的数据,这些数据易于解析和处理。相较于非结构…...

Go语言的数据类型

Go语言的数据类型详解 Go语言是一门具有简洁、高效并且强类型的编程语言。它的设计理念之一是让程序员能够以清晰、简明的方式表达自己的意图。在Go语言中,数据类型是其基础构建块之一,理解不同数据类型的特点和使用场景对于编写高效的Go程序至关重要。…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

数据链路层的主要功能是什么

数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析,分为​​已启动​​和​​未启动​​两种场景: 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​:当其他组件(如Activity、Service)通过ContentR…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...

SpringAI实战:ChatModel智能对话全解

一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM&#xff0…...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)

错误一:yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因,后面把yaml.safe_dump直接替换成yaml.dump,确实能保存,但出现乱码: 放弃yaml.dump,又切…...