Thread start/run方法分析

在线绘制富集分析多组气泡图和单细胞分析marker基因矩阵气泡图 常规的GO或者KEGG通路富集分析结果通常以气泡图的形式展示,然而这个气泡图仅仅是一个比较的结果,如果想在一张图上展示多个比较的结果,就需要用到多组气泡图(图1,左侧)。 单细胞RNA-seq分析结果中,矩阵形式的气泡图可以很好地展示marker基因(X轴)在不同cluster(Y轴)中的表达情况(图1,右侧)。 阅读详情

仔细琢磨 start 方法,我们可以得到很多结论

查看 Thread 中start 方法的源码

 public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

1. 线程无法被启动两次,有一个线程状态值 threadStatus 记录了线程状态(猜测应该是在start0()方法中赋值),如果重复启动,会抛出 IllegalThreadStateException 

2. 我们无法得知线程启动过程中做了什么,因为主要逻辑在本地方法 start0 当中,但不难知道,真正启动一个操作系统内核级线程并执行run方法中的任务也是在 start0 方法中进行的,java 线程是基于操作系统内核级线程进行映射的,所以最终需要借助于操作系统。

Java线程和操作系统线程的关系可参考https://blog.youkuaiyun.com/CringKong/article/details/79994511

3. 每个线程都有自己的私有堆栈,异常不能跨线程传播。

举个栗子,a线程中启动b线程b.start(),注意b线程真正开始执行是在start0()方法中,所以前面抛出的IllegalThreadStateException 属于a线程中抛出的异常。假如在执行start0方法时抛出运行时异常(意味着b线程启动失败),不进行catch操作,不处理异常信息,会被沿着调用堆栈(a线程的堆栈)上抛。同时finally语句块中保证了在start0出现异常,b线程启动失败后做相应的逻辑处理。

假如start0方法正常执行完毕,b线程成功启动,那么a,b线程将会在各自的堆栈中并发执行,互不影响。b线程在执行任务(执行run方法内容)过程中,假如出现了异常,它会沿着b线程的调用堆栈传递上抛,直至被 try catch捕捉,即使没有捕捉,它也不会影响a线程的执行。

4. Thread是Java语言本身对线程的抽象,也就是说在Java中,线程只有一种形式,那就是Thread的实例形式存在。

有一个经常被问的问题,创建线程有几种方式?我觉得这个问题其实不好,创建一个Thread的实例对象只有一个途径,那就是借助于new。而我们更多的是需要关注封装任务的方式,如何改变这个run方法为你需要的任务代码?

观察run方法的源码,可以发现我们其实只有两种方式,

1. 继承Thread,重新run方法

2. 通过构造方法,透传 Runnable 实例对象,对target进行赋值

单论创建线程,跟Runnable没必然关系,不用Runnable也能创建线程,任务封装才会涉及到Runnable。

3. 其实还有一种间接利用Runnable封装任务的方式,实现Callable接口,并且借助于FutureTask(关于这个,另做记录)

总结为

image_5c5bc7ee_2eb0

部分内容参考https://www.cnblogs.com/noteless/p/10354753.html强推

mcgs数据导出到U盘 mcgs触摸屏在工业中应用还是很多的,尤其他的脚本功能策略功能等将开放性放到了最大,让用户可以根据实际需求进行自由创作,正因为这样,对一些初学者就不是很友好,初学者想要简单操作就能实现功能,但是mcgs不可能两者兼备,在做工业设备,一些数据的采集保存就比较常见,但是mcgs没有相关按钮能够直接实现将数据导出到U盘的功能。这里我给大家讲解关于mcgs将报警历史记录、日志记录、历史数据记录导出到U盘的方法。 阅读详情

相关推荐

深入解析STM32定时器中央对齐模式3的双中断机制

本文深入解析了STM32定时器中央对齐模式3的双中断机制。该模式在一个PWM周期内,会在计数器到达ARR(上溢)和0(下溢)时各触发一次更新中断,实现更精细的实时控制。文章详细阐述了其工作原理、配置方法,并指导如何在中断服务函数中通过DIR位区分中断来源,同时探讨了其在电机控制、数字电源等场景下的应用优势与CPU负载挑战。

weixin_29164185的博客 493

Thread.start()方法解析

Thread.start()方法解析

m0_53232550的博客 3725

在Modelsim中手动添加仿真库

缘由:在使用rom ip核的时候发现仿真需要altera_mf库的支持,而我的ModelSim没有这个库,所以想写一篇手动添加仿真库的文章方便自己以后使用:首先新建一个库,名字叫做altera_mf:然后编译对应的库文件:这里altera_mf.v文件是在quartus安装路径下quartus\eda\sim_lib文件夹下,点击编译后退出:最后在modelsim->example文件夹下可以找到编译好的库文件:

欢迎一起交流问题! 3402

java线程无法start,为什么启动线程是start方法?

为什么启动线程是start方法十年可见春去秋来,百年可证生老病死,千年可叹王朝更替,万年可见斗转星移。凡人如果用一天的视野,去窥探百万年的天地,是否就如同井底之蛙?背景:启动线程是start() 还是run() 方法?相信这个问题很多人都知道是start(),但是如果我再问下去呢,为什么是start()?你会如何作答呢?一、理论课当用start()开始一个线程后,线程就进入就绪状态,使线程所代表的...

weixin_29131709的博客 642

基于拟蒙特卡洛模拟法的随机潮流计算matlab程序

由式(4-11)可知,蒙特卡洛模拟法的计算量不受电力系统规模大小影响,因此该方法在一些复杂的电力系统中可以得到应用,包括处理电力系统中有多个间歇性新能源接入的问题,解决系统中多个节点之间相关性问题等等。本章在此基础上提出了基于拟蒙特卡洛模拟的随机潮流计算方法,并且对拟蒙特卡洛法中的拟随机数序列进行了改进,大大提高了随机潮流的计算效率。模拟法的具体思路如下:基于实际工程问题的求解需要,建立与之相对应的随机模拟过程和随机概率模型,使得它们的参数,包括概率分布或者数学期望,能够等于问题的实际解;

weixin_47365903的博客 1798

汽车底盘技术解析:从悬架调校到智能化,如何评价国产车底盘实力

汽车底盘作为决定车辆驾驶质感、安全性和耐久性的核心系统,其技术内涵远不止于悬架结构。从行驶系、转向系到制动系的协同工作,底盘调校是一门融合机械原理与工程实践的艺术。在电动化与智能化浪潮下,底盘技术正经历从被动适应到主动响应的变革,CDC可变阻尼减震器和空气悬架等技术的应用,让底盘具备了通过OTA升级实现性能优化的可能。国产汽车品牌如奇瑞、吉利等,通过平台化架构研发与调校经验积累,正推动底盘技术从“能用”向“好用”乃至“塑造独特驾驶风格”迈进。理解底盘技术,需超越简单的结构对比,关注其在实际路况中的滤震性、支

weixin_34413103的博客 387

线程Thread类的start()方法和run()方法

一、初识 java的线程是通过java.lang.Thread类来实现的。VM启动时会有一个由主方法所定义的线程。可以通过创建Thread的实例来创建新的线程。每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体。通过调用Thread类的start()方法来启动一个线程。 在Java当中,...

weixin_34235135的博客 2197

分布式光纤传感(DFOS)DTS/DAS/DSS 三合一:10公里管线监测实战与数据解读

本文详细介绍了分布式光纤传感(DFOS)技术在10公里管线监测中的实战应用,通过DTS(温度)、DAS(振动)、DSS(应变)三合一系统,实现对管线健康状态的立体感知。文章涵盖工程部署、数据采集、多物理量数据融合及噪声抑制等关键技术,展示了如何通过一根光纤完成复杂监测任务,显著提升管线安全性和维护效率。

weixin_29168153的博客 316

java 启动时间有误_细品 Java 中启动线程的正确和错误方式

细品 Java 中启动线程的正确和错误方式前文回顾详细分析 Java 中实现多线程的方法有几种?(从本质上出发)start 方法和 run 方法的比较代码演示:/*** * start() 和 run() 的比较* ** @author 踏雪彡寻梅* @version 1.0* @date 2020/9/20 - 16:15* @since JDK1.8*/public class StartAn...

weixin_28695903的博客 165

GD32F103程序烧录全攻略:从SWD到串口的实战指南

本文提供了GD32F103微控制器程序烧录的全面实战指南,详细介绍了SWD、JTAG和串口(ISP)三种主流下载方式。文章重点解析了在Keil MDK中使用ST-Link进行SWD下载的完整步骤,包括硬件连接、软件配置和Flash算法设置,并针对烧录过程中的常见问题提供了实用的排坑解决方案,帮助开发者高效完成程序部署。

weixin_29191669的博客 438

9、自动定理证明的发展历程与关键技术

本文全面介绍了自动定理证明的发展历程、关键技术及其实际应用,包括消解原理、参数化、支撑集策略等核心方法,并探讨了算法优化、数据结构优化及并行计算等提升效率的手段。同时,文章展望了未来发展方向,如深度学习在定理证明中的应用、交互式定理证明以及高阶逻辑的研究前景。

ll5678的博客 508

线程池为什么能维持线程不释放,随时运行各种任务

接上一篇博文,对线程池如何实现线程复用,复习一下,以下是某位同学对Java线程池源代码的分析,参考参考,顺便mark一下: 之前一直有这个疑问:我们平时使用线程都是各种new Thread(),然后直接在run()方法里面执行我们要做的各种操作,使用完后需要做什么管理吗?线程池为什么能维持住核心线程不释放,一直接收任务进行处理呢? 线程 线程无他,主要有两个方法,我们先看看start()方法介绍:...

wangyunman的博客 3820

你分得清ChatGPT、Gemini、Grok、豆包、千问、DeepSeek、OpenClaw、CloudCode、vibeCodeing、sKill、MCP,飞书、微信这些到底是什么吗?

AI技术生态呈现层级化发展,从基础模型到应用平台形成完整技术栈。核心分为五层:模型层(GPT、Gemini等基础模型)→AI助手层(ChatGPT等应用产品)→工具层(ClaudeCode等开发工具)→协议层(MCP等接口标准)→应用层(微信、飞书等平台)。未来趋势将形成"模型公司-开发框架-应用生态"三层结构,AI正逐步演变为新型操作系统,通过标准化协议连接各类外部系统,实现能力调用与生态整合。技术发展呈现出从底层基础设施到上层应用场景的垂直整合特征。

hy行者勇哥的博客 400

问十:源码层面解析Thread中run()和start()的区别?

分析start()的源码: 调用start0()方法 是一个native方法 进入http://hg.openjdk.java.net/jdk8u源码页查看其native方法的源码 进入share目录,找到Thread.c 发现其调用了JVM_StartThread方法 通过查看其顶部引用,定位jvm.h 进入jvm.h进行查看 在JVM_S...

向代码提问 383

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Java中Thread 和Runnable 深入理解

Thread 和Runnable 关系 Thread类是接口Runnable的一个实现类。 public class Thread implements Runnable 复制代码源码分析 Thread Threa类运行的时候调用start()方法,源代码如下: 调用start()方法,实际运行的是start0方法,方法声明如下: private native void start0() ...

weixin_33984032的博客 186

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

JDK源码那些事儿之浅析Thread下篇

上一篇文章对Thread的状态转换和其中的部分源码进行了一个说明,今天继续对Thread源码进行解读,有很多涉及到底层的知识,笔者这里也只能进行简单了解,一起看一看吧

Orange's Life 293

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Thread基本认识

线程的认识直接调用run() 方法与直接调用start()方法的区别线程的创建方式 直接调用run() 方法与直接调用start()方法的区别 import java.util.concurrent.TimeUnit; public class WhatIsThread { private static class T1 extends Thread{ @Override...

追风筝的人 794

Thread

要实现线程调用带参数的方法有两种办法。 http://www.cnblogs.com/finered/archive/2011/07/23/2114687.html 很高上大的样子。。。不过,似乎不合用啊 Smart Thread Pool http://www.codeproject.com/Articles/7933/Smart-Thread-Pool#Feature4

白马酒凉 429

JUC-进程&线程

摘要 本文介绍了进程与线程的基本概念及其对比。进程具有并发性、动态性等特征,而线程是进程中的执行单元,共享进程资源但独立调度。一个进程可包含多个线程实现并发执行。线程相比进程更轻量,通信更简单,但进程间通信较为复杂,涉及信号量、共享存储、管道等方式。文章还详细阐述了Java中创建线程的三种方法:继承Thread类、实现Runnable接口和使用Callable接口,分析了各自的优缺点,并介绍了Thread类的常用API方法。

qq_40589140的博客 630

JAVA多线程

是进程中的单个顺序控制流,是一条执行路径。一个进程如果只有一条执行路径,则称为单线程程序一个进程如果有多条执行路径,则称为多线程程序:是正在运行的软件:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位。:进程的实质是程序的一次执行过程,进程是动态产生,动态消亡的。:任何进程都可以同其他进程一起并发执行指两个或多个事件在同一时间间隔内发生。这些事件宏观上是同时发生的,但微观上是交替发生的。指两个或多个事件在同一时刻同时发生。

gaohe26AIliuzeyu的博客 290

进阶笔录- 并发编程之深入理解Java线程

使用new Thread(创建一个线程,然后调用start()方法进行java层面的线程启动);调用本地方法start0(),去调用jvm中的JVM_StartThread方法进行线程创建和启动;调用new JavaThread(8thread entry, sz)进行线程的创建,并根据不同的操作系统平台调用对应的os:create _thread方法进行线程创建;...

我是个小佬 422

JUC并发编程【八股篇】:并发基础

本文系统梳理了Java并发编程的基础知识,重点探讨了进程与线程的本质区别、并发编程的优势与挑战,以及线程创建的四种方式。文章指出线程是CPU调度的最小单位,共享进程资源但拥有独立程序计数器,并详细分析了Java线程状态与操作系统状态的映射关系。在并发挑战部分,深入讲解了死锁条件、线程安全问题和资源限制的应对策略。最后比较了四种线程创建方式的优缺点,强调Runnable方式解耦任务与执行者的设计优势。全文为理解并发编程核心概念提供了清晰框架。

感谢阅读。 1701

并发编程(上)Synchronized 、LockSupport 、ReentrantLock

一、基本概念 1、进程与线程 进程 程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至 CPU,数据加载至内存。在指令运行过程中还需要用到磁盘、网络等设备。进程就是用来加载指令、管理内存、管理 IO 的。 当一个程序被运行,从磁盘加载这个程序的代码至内存,这时就开启了一个进程。 进程就可以视为程序的一个实例。大部分程序可以同时运行多个实例进程(例如记事本、画图、浏览器 等),也有的程序只能启动一个实例进程(例如网易云音乐、360 安全卫士等) 线程 一个进程之内可以分为一到多个线程。

qq_43744488的博客 1306

Thread中的start和run方法的区别

面试必问,面试必问,面试必问!别问我为什么知道~~ 总结 run()只是Thread类的一个普通方法,调用run()并不会新建一个子线程,仍在主线程执行任务。 调用start()会新建一个子线程并执行run()的内容。调用start()会有两个线程,一个是当前正在调用start()的主线程;另一个是JVM创建的子线程,用来执行run()的内容。 实践 实践出真知~~首先写下测试代码: publ...

joy_pan的博客 2182

为什么start方法会调用run方法?(为什么不能直接run来实现创建线程?)

我们知道再创建线程的时候是使用Thread类中的start方法,那么为什么不直接用Thread类中的run方法呢? 来直接上源码: Thread中的run方法如下。 那么target是什么呢? 我们可以看到是一个Runable对象。那么Thread类中的run方法就是说:如果有Runnable子类对象(当然Runable是接口,没有直接对象),就会调用run方法,如果没有该对象,则什么操作都...

吴成伟的博客 3485

Java多线程-Thread类的run方法

Java中的线程是基于操作系统的原生线程实现的,而start0()方法主要就是与操作系统进行交互,创建和启动新的系统级线程。以上执行逻辑可能因不同的JVM实现和不同的操作系统有所不同,具体实现代码可以在JVM的源代码中找到。(3)在新的系统级线程上调用Java线程对象的run()方法。通过上面的分析,要让线程执行某段逻辑的关键是,实现run方法。(2)传入一个实现了run方法的Runnable接口的实现类。(2)将Java线程对象与新创建的系统级线程进行关联。(1)申请系统资源创建一个新的系统级线程。

南七行者的博客 2212
上一篇: Thread构造方法分析
下一篇: 为什么使用多线程,多线程如何提高效率
MrMoving
博客等级 码龄10年 54粉丝 145原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值