Java中线程创建以及线程的生命周期

单片机入门说明书:从本质到架构,一文看透MCU核心原理 其实你每天用的洗衣机、刷的智能门锁、开的汽车里,都藏着它的身影。相当于工厂里的“运输轨道”,CPU算出的结果通过总线送到RAM存储,ROM里的程序通过总线传给CPU执行,外设的信号通过总线交给CPU处理,整个过程每秒能重复上百万次,确保各模块协同高效。高端单片机(比如STM32F4系列)还会配备DMA(直接存储器访问)单元,相当于“专用传送带”——不需要CPU干预,就能直接让外设和RAM之间传输数据(比如让ADC采集的温度数据直接存进RAM),大大降低CPU负担,让CPU能专注处理更重要的任务。 阅读详情

线程和进程

进程:计算机中有特定功能的应用程序在内存中的一次运行(如迅雷下载在电脑上的启动)

线程:线程是进程的一个单元(如利用迅雷下载某个资源)

多线程:一个进程中有多个线程同时存在运行(如我们用迅雷同时下载好多不同资源)

在我们JAVA中,虚拟机JVM是多线程的,例如JVM在逐条运行字节码时是一套线程,同时垃圾回收线程也在回首那些未被引用的对象。虚拟机允许应用程序并发运行多个执行的线程。

线程的创建

执行线程有两种创建方法,一种是将类声明为Thread的子类,这时这个类就必须要重写父类的run()方法,然后我们就可以分配并启动该子类的实例。

我们新建线程类:

package ThreadDemo;

public class ThreadTest extends Thread {
    //run()方法中的代码即为线程块
    @Override
    public void run() {
        for (int i = 0; i <10 ; i++) {
            System.out.println(this.getName()+"说第"+i+"次,欢迎您!");
        }
    }
}

测试类如下

package ThreadDemo;

public class TestMain {
    public static void main(String[] args) {
        //创建线程的实例对象
        ThreadTest tt1=new ThreadTest();
        ThreadTest tt2=new ThreadTest();
        //为线程命名
        tt1.setName("线程一");
        tt2.setName("线程二");
        //启动线程
        tt2.start();
        tt1.start();
    }
}

执行结果如下,可以看到线程一和线程二交叉执行并无先后约定


创建线程的另外一种方法是声明实现Runnable接口,当然的该类要实现run()方法,然后便可以分配该类的实例。

package runnableDemo;

public class RunnableTest implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i <10 ; i++) {
            System.out.println(Thread.currentThread().getName()+"说第"+i+"次,欢迎您!");
        }
    }
}

创建测试类

package runnableDemo;

public class TestMain {
    public static void main(String[] args) {
        //实例化一个线程对象
        RunnableTest rt=new RunnableTest();
        //新建两个线程
        Thread t1=new Thread(rt,"线程1");
        Thread t2=new Thread(rt,"线程2");
        //启动线程
        t1.start();
        t2.start();
    }
}

执行结果如下,可以看到线程一和线程二交叉执行并无先后约定


线程的并发执行并非我算所看到的几个线程同时执行,而是CPU资源每次只能随机分配给一个线程,当这个线程执行完毕后,再次随机分配,所以线程的执行顺序是随机的,而CPU的执行速度是非常快的,才会让我们感觉是所有线程同时执行的。

线程的生命周期

注:这次部分转载自https://www.cnblogs.com/sunddenly/p/4106562.html

        当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。在线程的生命周期中,它要经过新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)5种状态。尤其是当线程启动以后,它不可能一直"霸占"着CPU独自运行,所以CPU需要在多条线程之间切换,于是线程状态也会多次在运行、阻塞之间切换

 

        1. 新建状态,当程序使用new关键字创建了一个线程之后,该线程就处于新建状态,此时仅由JVM为其分配内存,并初始化其成员变量的值

 

        2. 就绪状态,当线程对象调用了start()方法之后,该线程处于就绪状态。Java虚拟机会为其创建方法调用栈和程序计数器,等待调度运行

 

        3. 运行状态,如果处于就绪状态的线程获得了CPU,开始执行run()方法的线程执行体,则该线程处于运行状态

 

        4. 阻塞状态,当处于运行状态的线程失去所占用资源之后,便进入阻塞状态

一、新建和就绪状态

        当程序使用new关键字创建了一个线程之后,该线程就处于新建状态,此时它和其他的Java对象一样,仅仅由Java虚拟机为其分配内存,并初始化其成员变量的值。此时的线程对象没有表现出任何线程的动态特征,程序也不会执行线程的线程执行体。

 

        当线程对象调用了start()方法之后,该线程处于就绪状态。Java虚拟机会为其创建方法调用栈和程序计数器,处于这个状态中的线程并没有开始运行,只是表示该线程可以运行了。至于该线程何时开始运行,取决于JVM里线程调度器的调度。

 

        注意:启动线程使用start()方法,而不是run()方法。永远不要调用线程对象的run()方法。调用start0方法来启动线程,系统会把该run()方法当成线程执行体来处理;但如果直按调用线程对象的run()方法,则run()方法立即就会被执行,而且在run()方法返回之前其他线程无法并发执行。也就是说,系统把线程对象当成一个普通对象,而run()方法也是一个普通方法,而不是线程执行体。需要指出的是,调用了线程的run()方法之后,该线程已经不再处于新建状态,不要再次调用线程对象的start()方法。只能对处于新建状态的线程调用start()方法,否则将引发IllegaIThreadStateExccption异常。

        调用线程对象的start()方法之后,该线程立即进入就绪状态——就绪状态相当于"等待执行",但该线程并未真正进入运行状态。如果希望调用子线程的start()方法后子线程立即开始执行,程序可以使用Thread.sleep(1) 来让当前运行的线程(主线程)睡眠1毫秒,1毫秒就够了,因为在这1毫秒内CPU不会空闲,它会去执行另一个处于就绪状态的线程,这样就可以让子线程立即开始执行。

 

二、运行和阻塞状态

2.1 线程调度

        如果处于就绪状态的线程获得了CPU,开始执行run()方法的线程执行体,则该线程处于运行状态,如果计算机只有一个CPU。那么在任何时刻只有一个线程处于运行状态,当然在一个多处理器的机器上,将会有多个线程并行执行;当线程数大于处理器数时,依然会存在多个线程在同一个CPU上轮换的现象。

 

        当一个线程开始运行后,它不可能一直处于运行状态(除非它的线程执行体足够短,瞬间就执行结束了)。线程在运行过程中需要被中断,目的是使其他线程获得执行的机会,线程调度的细节取决于底层平台所采用的策略。对于采用抢占式策略的系统而言,系统会给每个可执行的线程一个小时间段来处理任务;当该时间段用完后,系统就会剥夺该线程所占用的资源,让其他线程获得执行的机会。在选择下一个线程时,系统会考虑线程的优先级。

 

        所有现代的桌面和服务器操作系统都采用抢占式调度策略,但一些小型设备如手机则可能采用协作式调度策略,在这样的系统中,只有当一个线程调用了它的sleep()或yield()方法后才会放弃所占用的资源——也就是必须由该线程主动放弃所占用的资源。

 

2.2 线程阻塞

        当发生如下情况时,线程将会进入阻塞状态

 

        ① 线程调用sleep()方法主动放弃所占用的处理器资源

 

        ② 线程调用了一个阻塞式IO方法,在该方法返回之前,该线程被阻塞

 

        ③ 线程试图获得一个同步监视器,但该同步监视器正被其他线程所持有。关于同步监视器的知识、后面将存更深入的介绍

 

        ④ 线程在等待某个通知(notify)

 

        ⑤ 程序调用了线程的suspend()方法将该线程挂起。但这个方法容易导致死锁,所以应该尽量避免使用该方法

 

        当前正在执行的线程被阻塞之后,其他线程就可以获得执行的机会。被阻塞的线程会在合适的时候重新进入就绪状态,注意是就绪状态而不是运行状态。也就是说,被阻塞线程的阻塞解除后,必须重新等待线程调度器再次调度它。

 

2.3 解除阻塞

        针对上面几种情况,当发生如下特定的情况时可以解除上面的阻塞,让该线程重新进入就绪状态:

 

        ① 调用sleep()方法的线程经过了指定时间。

 

        ② 线程调用的阻塞式IO方法已经返回。

 

        ③ 线程成功地获得了试图取得的同步监视器。

 

        ④ 线程正在等待某个通知时,其他线程发出了个通知。

 

        ⑤ 处于挂起状态的线程被调甩了resdme()恢复方法。

 

                                          图 2.1 线程状态转换图

        从图2.1中可以看出,线程从阻塞状态只能进入就绪状态,无法直接进入运行状态。而就绪和运行状态之间的转换通常不受程序控制,而是由系统线程调度所决定。当处于就绪状态的线程获得处理器资源时,该线程进入运行状态;当处于运行状态的线程失去处理器资源时,该线程进入就绪状态。但有一个方法例外,调用yield()方法可以让运行状态的线程转入就绪状态。关于yield()方法后面有更详细的介纽。

三、线程死亡

3.1 死亡状态

        线程会以如下3种方式结束,结束后就处于死亡状态:

 

        ① run()或call()方法执行完成,线程正常结束。

 

        ② 线程抛出一个未捕获的Exception或Error。

 

        ③ 直接调用该线程stop()方法来结束该线程——该方法容易导致死锁,通常不推荐使用




innovus:ccopt_design流程 我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧?spec文件可以只创建一次,无需多次创建。2)virtual balance阶段。3)Full Balancing阶段。4)Clock Routing阶段。1)clustering阶段。 阅读详情

相关推荐

Xilinx IP核 Block Memory Generator v8.4 的使用

本文主要介绍如何使用并初始化 Xilinx 提供的IP核 Block Memory Generator v8.4`,为了确保成功初始化,还对其进行了一个简单的仿真,更多细节请参考官方手册。

高阶近似的博客 1万+

线程的创建及线程的状态

一:创建多线程 方法一:继承Thread类 可以通过继承 Thread 来创建一个线程类,该方法的好处是 this 代表的就是当前线程,不需要通过 Thread.currentThread() 来获取当前线程的引用。 class MyThread extends Thread { @Override public void run() { System.out.println("这...

zhanghongkai0916的博客 333

智能体在车联网中的应用:第19天 智能体理论与初步实践 D30:阶段小结——在SUMO中使用TraCI控制预编程智能体

本文介绍了如何将强化学习从算法仿真迁移到交通系统实践,重点讲解了SUMO微观交通仿真平台与TraCI实时控制接口的架构。通过构建一个预编程驾驶智能体,演示了车辆从起点到目标点的导航控制。文章详细解析了TraCI的双向通信机制和事件驱动模型,对比了其与传统RL环境的差异,并提供了完整的Python实现框架,包括路网配置、车辆控制和基于向量场的导航逻辑。该实践为后续开发高级学习型交通智能体奠定了基础。

IT深耕十余载,大道之简 1478

线程的创建 以及 线程的各种状态

创建线程类:  第一种extends老方法 继承 (缺点 java害怕单继承 和 无法实现资源共享) 第二种 实现runnable接口 建立个线程资源类 run为具体操作 然后基于该类建立多个线程 这时候由于只有一个资源类实例 所以资源共享 注意:使用第二种方案最多 java不允许多继承 implement方式 资源不具备start方法 必须thread对象才可以 可以单可以多 线

yuliangliang092的博客 996

AArch64 ARM64 寄存器介绍

除了上述通用寄存器,还有FPSR(浮点状态寄存器)和 FPCR(浮点控制寄存器)等。X29寄存器和X30寄存器在函数调用和堆栈帧的管理中扮演着关键角色。AArch64架构提供了31个通用寄存器,每个寄存器都可以用作64位X寄存器(X0~X30)或32位W寄存器(W0~W30)。使用X寄存器将导致64位的计算,使用W寄存器将导致32位的计算。EL0、EL1、EL2和EL3是AArch64架构中定义的四个特权级别(Exception Levels),用于支持不同的执行环境和特权级别。

lml435035844的博客 1万+

别再让信号‘撞墙’了!手把手教你用嘉立创阻抗计算器搞定PCB高速线(附免费压层结构选择)

本文详细介绍了如何使用嘉立创阻抗计算器解决PCB高速线设计中的阻抗匹配问题,避免信号反射和传输损耗。通过免费压层结构选择和五步计算法,帮助工程师快速掌握USB3.0差分线等高速信号的设计技巧,提升PCB设计效率和信号质量。

weixin_30736301的博客 278

线程的创建和睡眠

一、线程 两种创建线程的区别在于Thread创建线程不可以多次start,第二次start就会报异常!Runnable这种的就不会报异常。 (Thread)(Java) 创建一个线程 new Thread() { @Override public void run() { super.run(); ...

u012928069的博客 474

S32K314 EB配置MCAL全模块讲解【Autosar——1 MCU模块详解】持续更新中

FIRC(fast internal RC Oscillator) :高速内部时钟,固定48MHZ;SIRC(Slow Internal RC Oscillator):低速内部时钟,固定32KHZ;FXOSC(Fast Crystal Oscillator Digital Controller):高速外部晶振(8-40MHZ),根据原理图选型进行配置;SXOSC():外部低速外部时钟,固定输入32.768KHZ;PLL_PHIn_CLK:时钟倍频锁相环时钟范围(640-1280MHZ);

qq_40488886的博客 1779

Java线程生命周期详解

Java中的线程生命周期是多线程开发的核心概念。了解线程的生命周期以及它们如何进行状态转换对于编写有效且无错误的多线程程序至关重要。

沐雨风栉 6840

把 ABAP 经验装进 GitHub Copilot 的按需大脑,Agent Skills 如何改变 ABAP 开发

2026 年 8 月,SAP Community 上出现了一次很有代表性的 ABAP 实验。开发者把标准 Flight Model 里的复制成自己的测试类,删除原有 ABAP Unit Test,再让 GitHub Copilot Agent 为方法重新生成测试代码。真正有意思的地方并不是 Copilot 会不会写,而是开发者给 Copilot 准备了两个专门的 Agent Skills,一个负责 ABAP Unit Test 的通用规则,一个负责 ABAP Test Double Framework。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 153

解锁PyCharm+Deepseek:本地部署AI编程超能力

在本次探索中,我们成功地在 PyCharm 中实现了 DeepSeek 的本地化部署,这一过程虽然涉及多个步骤,但每一步都为我们开启 AI 编程大门奠定了基础。从安装最新版 PyCharm,确保我们拥有一个功能强大且兼容性良好的开发环境,到注册 DeepSeek 账号并获取 API Key,这是连接我们与强大 AI 能力的关键纽带。接着,在 PyCharm 中安装 Continue 插件并进行精细配置,让 DeepSeek 能够深度融入我们的编程流程。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 5548

线程池ThreadPoolExecutor中线程的创建与销毁

线程池ThreadPoolExecutor中线程的创建与销毁

weixin_37873870的博客 6437

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Java中线程的生命周期

本篇文章我们讨论下Java中的一个非常核心的概念:线程的生命周期。在Java编程语言中,多线程编程非常重要。线程从创建到销毁是有生命周期的,在线程的生命周期中,线程会经历多种状态(state)。线程是Java多线程编程的基础,本文讨论了Java中线程的生命周期,以及生命周期中可能出现的6种状态,每种状态都举例进行了说明。内容主要来源于: java-thread-lifecycle。

qq_66627105的博客 1594

android 蓝牙通讯demo

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

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

java中,线程的生命周期

java中,线程的生命周期 一、什么是线程? 见之前写的。 当线程启动后(线程对象调用start方法),它不能一直"独占"着CPU独自运行,所以CPU需要在多条线程之间切换,于是线程状态也会多次在运行、阻塞之间切换。 二、线程的生命周期是什么? 在线程的生命周期中: 它要经过新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)五种状态。 新建...

SeniorShen的博客 1万+

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

java中线程的创建方式-休眠-生命周期-工作方式

/ 线程: Thread就是线程类// Thread.currentThread() 获取当前正在运行的线程// getName获取线程的名称// main// 创建1个线程对象// 开始启动这个线程t1.start();// ctrl+o可以重写@Override// 输出 线程名称:Thread-0System.out.println("线程名称:"+Thread.currentThread().getName());

dsgdauigfs的博客 805

Java 多线程生命周期和创建(转)

  转自:http://www.cnblogs.com/lwbqqyumidi/p/3804883.html   多线程作为Java中很重要的一个知识点,在此还是有必要总结一下的。 一.线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的图: 上图中基本上囊括了Java中多线程各重要知识点。掌握了上图中的各知识点,Java中的多线程也就基本上掌...

bug_yun的博客 156

Java线程生命生命周期_初步学习Java中线程的实现与生命周期

这篇文章主要介绍了初步学习Java中线程的实现与生命周期,线程方面的知识是Java学习过程中的重点和难点,需要的朋友可以参考下线程的实现  在Java中通过run方法为线程指明要完成的任务,有两种技术来为线程提供run方法:1.继承Thread类并重写它的run方法。之后创建这个子类的对象并调用start()方法。2.通过定义实现Runnable接口的类进而实现run方法。这个类的对象在创建Thr...

weixin_29113371的博客 116

操作系统与Java中线程的生命周期和线程状态

1 操作系统中的线程状态 创建:线程从创建到被cpu执行之前的这个阶段。 就绪:指线程已具备各种执行条件,一旦获取cpu便可执行。 运行:表示线程正获得cpu在运行。 阻塞:指线程在执行中因某件事而受阻,处于暂停执行的状态,阻塞的线程不会去竞争cpu。 终止:线程执行完毕,接下来会释放线程占用的资源。 线程的生命周期图如下(进程与线程生命周期一样): 2 Java中线程的状态 T............

奋进的小白粥 1229

【Java多线程-1】线程概述与线程创建和使用

说到程序,离不开进程和线程这两个概念。那么这两者分别有什么作用和区别呢? 1 线程概述 进程是表示资源分配的基本单位,又是调度运行的基本单位。例如,用户运行自己的程序,系统就创建一个进程,并为它分配资源,包括各种表格、内存空间、磁盘空间、I/O设备等。然后,把该进程放人进程的就绪队列。进程调度程序选中它,为它分配CPU以及其它有关资源,该进程才真正运行。所以,进程是系统中的并发执行的单位。如下图所...

云深不知处 1万+

java多线程实现和常用的方法

1、线程 1.1线程的概念 ...

qq_41176163的博客 163

Java 中线程的使用

本文主要介绍了,java 中怎么去使用线程 Thread 类,包括线程的创建方式,单线程与多线程的使用,用户线程与守护线程,死锁与互斥锁。

weixin_74200123的博客 1072

java第十六课(线程,多线程,Thread,Lock,线程通信)

程序为完成特定任务,用某种语言编写的一组指令的集合,就是一段静态代码(安装在电脑上的文件键)进程也是程序但是是运行中的程序 是操作系统进行资源分配的最小单位线程线程可以进一步细化为进程,进程中的一个最小执行单元就是线程,是cpu进行调度的最小单元。

2302_78076476的博客 1124

Java中的线程创建和同步快速入门(保姆级教程)

当 Java 程序启动时,它会创建一个主线程(main线程),并可能会启动其他子线程。程序会等待所有用户线程完成后才会终止。守护线程:与用户线程不同,守护线程是用来在后台执行支持性任务的,当所有用户线程结束时,守护线程会自动终止,不管它是否完成了自己的任务。

Logic-Driven Thought Engineering 1298

Java多线程系列详解_01_线程的创建和启动

本文主要讲线程的两种创建方式以及启动线程线程的释义(What)为什么要有线程(Why)线程的创建方式线程的启动 线程的释义(What) 百度百科如下: 为什么要有线程(Why) 在Java中很多文件IO操作和网络IO操作都是比较耗时的,比如下载10个文件到本地,这时一般的程序会一个一个 文件的下载,加入使用多线程操作会将10个文件同时下载,这个时候会节省好多时间. 本文的例子是读取数据库内容并写入本地文件,话不多说,让我们一起看代码吧! 线程的创建方式 未使用多线程之前 /** * @a

Alone5256的博客 312
上一篇: JavaAPI之网络编程UDP/TCP简述及示例
下一篇: Java线程并发及同步锁synchronized的应用
madi_Goly
博客等级 码龄16年 11粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值