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

Java多线程-Thread类的run方法

Java多线程-Thread类的run方法

  • 一、背景
  • 二、研究Thread类的start()源码
    • 1、源码(比较短,贴一下)
      • 1.1 重点:start0();
  • 三、研究Thread类的run()源码
    • 1、源码(很关键,必须贴)
  • 四、创建线程的2种方式
    • 1、继承Thread,并覆写run方法
    • 2、传入一个实现了run方法的Runnable接口的实现类
  • 五、到底执行哪个run方法?

一、背景

  • 在Java中,要使用多线程,很显然先要创建线程。
  • Java将线程抽象为Thread类。创建线程的第一步:new Thread()
  • 创建好Thread对象后,接下来,就是要启动线程,并执行线程需要做的事情:Thread对象.start();
    (1)首先会启动线程;
    (2)然后调用run方法();

二、研究Thread类的start()源码

1、源码(比较短,贴一下)

public synchronized void start() {if (threadStatus != 0)throw new IllegalThreadStateException();group.add(this);boolean started = false;try {start0();started = true;} finally {try {if (!started) {group.threadStartFailed(this);}} catch (Throwable ignore) {}}
}

1.1 重点:start0();

  • 源码
private native void start0();
  • 是一个本地方法。也很好理解,Java的线程是交由操作系统来管理的。

start0()方法是Java中的一个本地方法,也就是说它是用其他语言(通常是C或C++)实现的。
其主要逻辑是创建一个新的系统级线程,并在新线程上执行run()方法
Java中的线程是基于操作系统的原生线程实现的,而start0()方法主要就是与操作系统进行交互,创建和启动新的系统级线程。
具体来说,start0()方法的执行逻辑一般包括以下步骤:
(1)申请系统资源创建一个新的系统级线程。
(2)将Java线程对象与新创建的系统级线程进行关联。
(3)设置线程的优先级和栈大小等线程属性。
(3)在新的系统级线程上调用Java线程对象的run()方法。
(4)如果run()方法执行结束或发生异常,清理系统级线程资源。
以上执行逻辑可能因不同的JVM实现和不同的操作系统有所不同,具体实现代码可以在JVM的源代码中找到。

三、研究Thread类的run()源码

1、源码(很关键,必须贴)

@Override
public void run() {if (target != null) {target.run();}
}
  • Thread类:public class Thread implements Runnable

Runnable的源码:

@FunctionalInterface
public interface Runnable {public abstract void run();
}

既然Thread类实现了Runnable接口,就要覆写run方法。

  • target是什么?
public class Thread implements Runnable {......private Runnable target;......
}
  • 用户可以通过这个构造方法传入target:
public Thread(Runnable target) {init(null, target, "Thread-" + nextThreadNum(), 0);
}

四、创建线程的2种方式

通过上面的分析,要让线程执行某段逻辑的关键是,实现run方法。
有2种方式:
(1)继承Thread,并覆写run方法
(2)传入一个实现了run方法的Runnable接口的实现类

1、继承Thread,并覆写run方法

  • 示例
public class PrintEvenThread extends Thread {@Overridepublic void run() {// 遍历100以内的偶数for (int i = 0; i < 100; i++) {if (i % 2 == 0) {System.out.println(Thread.currentThread().getName() + ":" + i);}}}
}public class PrintOddThread extends Thread {@Overridepublic void run() {// 遍历100以内的奇数for (int i = 0; i < 100; i++) {if (i % 2 != 0) {System.out.println(Thread.currentThread().getName() + ":" + i);}}}
}
public class PrintThreadTest {@Testpublic void testTwoPrintThread() {PrintEvenThread printEvenThread = new PrintEvenThread();PrintOddThread printOddThread = new PrintOddThread();printEvenThread.start();printOddThread.start();}
}
  • 还可以:匿名类的匿名对象的方式
new Thread() {@Overridepublic void run() {for (int i = 0; i < 100; i++) {if (i % 2 != 0) {System.out.println(Thread.currentThread().getName() + ":" + i);}}}
}.start();

2、传入一个实现了run方法的Runnable接口的实现类

  • 示例 (匿名类的匿名对象)
public class LearnCreateThreadMain3 {public static void main(String[] args) {new Thread(new PrintEven()).start();}
}class PrintEven implements Runnable {@Overridepublic void run() {for (int i = 0; i < 10; i++) {if (i % 2 == 0) {System.out.println(i);}}}
}
  • 还可以:匿名类的匿名对象的方式
new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i < 100; i++) {if (i % 2 != 0) {System.out.println(Thread.currentThread().getName() + ":" + i);}}}}).start();

五、到底执行哪个run方法?

  • 示例
public class LearnCreateThreadMain4 {public static void main(String[] args) {Hi hi = new Hi();new Thread(hi) {@Overridepublic void run() {System.out.println("hello~");}}.start();}
}class Hi implements Runnable {@Overridepublic void run() {System.out.println("Hi~");}
}
  • 看懂了“三、研究Thread类的run()源码”,很容易回答:执行的是Thread子类对象的run方法。也就是输出:hello~
  • 如果子类没有覆写Thread的run()方法,那么执行的代码是:
@Override
public void run() {if (target != null) {target.run();}
}
  • 一旦子类覆写了,那执行的就是子类的run()方法了。

相关文章:

Java多线程-Thread类的run方法

Java多线程-Thread类的run方法 一、背景二、研究Thread类的start()源码1、源码&#xff08;比较短&#xff0c;贴一下&#xff09;1.1 重点&#xff1a;start0(); 三、研究Thread类的run()源码1、源码&#xff08;很关键&#xff0c;必须贴&#xff09; 四、创建线程的2种方式1…...

java基础之Java8新特性-方法引入

目录 1.简介 2.方法引入 方法引入遵循规范 方法引入种类 1.静态方法引入 2.对象方法引入 3.实例方法引入 4.构造函数引入 1.简介 方法引用是 Java 8 中引入的另一个重要特性&#xff0c;它提供了一种简洁的语法来直接引用现有方法或构造函数。方法引用可以看作是 Lambd…...

K8S中的hostPort、NodePort 、targetPort、port、containerPort 的区别

Dockerfile的EXPOSE Dockerfile中端口的声明: EXPOSE <端口1> [<端口2>...] 所以:EXPOSE的 第一个作用:只是说明docker容器开放了哪些端口,并没有将这些端口实际开放了出来!更多的作用是告诉运维人员或容器操作人员我开放了容器的哪些端口,只是一种说明。 …...

SpringBoot整合FreeMarker模板引擎

中文官方参考手册 http://freemarker.foofun.cn/ 1.先加入FreeMarker依赖 <dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.23</version> </dependency>2.新建一个FreeMark…...

编程基础 - 变量与常量

编程基础 - 变量与常量 返回序言及专栏目录 文章目录 编程基础 - 变量与常量前言一、变量是什么&#xff1f;二、为什么要有变量三、局部变量和全局变量四、常量五、只读变量小结 前言 变量是编程最重要知识点之一&#xff0c;从根本上讲&#xff0c;编程就是对数据的操作&a…...

Linux入门攻坚——12、Linux网络属性配置相关知识2

CentOS 7网络属性配置&#xff1a; 传统命名机制&#xff1a;以太网eth[0,1,2,...]&#xff0c;wlan[0,1,2...] 可预测功能的命名机制&#xff1a; udev支持多种不同的命名方案&#xff1a; Firmware &#xff0c;拓扑结构 在对待设备文件这块&#xff0c;Linux改…...

如何自己实现一个分布式事务

实现分布式事务是一个复杂的过程&#xff0c;它需要精心设计并考虑数据的一致性、系统的可用性和分区容错能力。分布式事务确保在分布式系统中&#xff0c;即使是跨多个数据库、服务或消息队列&#xff0c;事务要么完全成功&#xff0c;要么完全失败。 以下是实现分布式事务的…...

使用Nonebot编写QQ机器人

使用 NoneBot 这个工具&#xff0c;来编写 QQ 机器人。 安装基础软件 一、安装 NoneBot 库 直接使用 pip 安装即可 pip install nonebot二、安装酷Q 软件和 HTTP API 插件 酷Q 软件可以直接到官网下载&#xff0c;https://cqp.cc/b/news&#xff0c;或者可以到网盘下载&am…...

认识SpringBoot中的条件注解

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 循序渐进学SpringBoot ✨特色专栏&…...

使用PAI-DSW搭建基于LangChain的检索知识库问答机器人

教程简述 在本教程中&#xff0c;您将学习如何在阿里云交互式建模&#xff08;PAI-DSW&#xff09;中&#xff0c;基于LangChain的检索知识库实现知识问答。旨在建立一套对中文场景与开源模型支持友好、可离线运行的知识库问答解决方案。 LangChain是一个开源的框架&#xff0c…...

优雅的通过Shell脚本生成Go的程序包

前言 随着Go语言的普及&#xff0c;越来越多的开发人员选择使用Go编写代码。虽然越来越多的公司项目已使用持续集成/持续部署&#xff08;CI/CD&#xff09;工具&#xff0c;用于自动化构建、测试和部署Go程序包&#xff0c;但存在一些部署在ECS服务器的Go程序包或需要手动编译…...

益生菌抗癌?补充这种益生菌,抑制肝癌,还改善肠道健康

撰文 | 宋文法 肠道菌群&#xff0c;是人体不可分割的组成部分&#xff0c;生活在我们肠道内的数万亿细菌对健康起着重要作用&#xff0c;它们影响着人的新陈代谢、消化能力、抵御感染、控制人体对药物的反应&#xff0c;甚至还能预防某些癌症。 非酒精性脂肪肝病&#xff0c;是…...

LLM漫谈(二)| QAnything支持任意格式文件或数据库的本地知识库问答系统

一、QAnything介绍 QAnything (Question and Answer based on Anything) 是致力于支持任意格式文件或数据库的本地知识库问答系统&#xff0c;可断网安装使用。 您的任何格式的本地文件都可以往里扔&#xff0c;即可获得准确、快速、靠谱的问答体验。 目前已支持格式: PDF&…...

Linux环境vscode clang-format格式化:vscode clang format command is not available亲测有效!

问题现象 vscode安装了clang-format插件&#xff0c;但是使用就报错 问题原因 设置中配置的clang-format插件工具路径不正确。 解决方案-亲测有效&#xff01; 确认本地安装了clang-format工具&#xff1a;终端输入clang-format&#xff08;也可能是clang-format-13等版本…...

Vue3前端 响应式数据 知识点

一、ref(基本类型数据&#xff0c;也可以定义对象类型的响应式数据。此时底层用的还是reactive) ref 创建基本类型的响应式数据 作用:定义响应式变量语法: let xxx ref(初始值)返回值: 一个 RefImp1 的实例对象&#xff0c;简称 ref对象或ref&#xff0c;ref 对象的 value 属…...

golang数据库连接池设置多少比较合适,如何设置?

设置数据库连接池的大小需要综合考虑应用程序的需求、数据库系统的性能、服务器资源等因素。连接池大小的不合理设置可能导致性能问题或资源浪费。 以下是一些建议&#xff1a; 考虑应用程序的并发需求&#xff1a; 连接池的大小应该足够满足应用程序的并发需求。如果你的应用…...

一、Mybatis 简介

本章概要 简介持久层框架对比快速入门&#xff08;基于Mybatis3方式&#xff09; 1.1 简介 https://mybatis.org/mybatis-3/zh/index.html MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁移到了Google Code。随着开发团队转投G…...

苹果Vision Pro将于1月27日上市!

在无数期待中&#xff0c;苹果全新产品Vision Pro头显终于定下上市日期。 彭博社记者马克古曼&#xff08;Mark Gurman&#xff09;于近日在X&#xff08;前推特&#xff09;平台爆料了这一信息&#xff0c;预计苹果Vision Pro头显将于2024年1月27日率先在美国上市。 在过去看…...

密码学(一)

文章目录 前言一、Cryptographic Primitives二、Cryptographic Keys2.1 Symmetric key cryptography2.2 asymmetric key cryptography 三、Confidentiality3.1 Symmetric key encryption algorithms3.2 asymmetric key block ciphers3.3 其他 四、Integrity4.1 secure hashing …...

VueRouter

1、用户权限问题 可以在路由全局前置守卫判断当前vuex里是否有token 有token值证明刚才登录过, 无token值证明未登录 router.beforeEach((to, from, next) > {const token store.state.tokenif (token) {// 如果有token, 证明已登录if (!store.state.userInfo.username) {/…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...