多线程-Thread类的常用方法和生命周期

news2024/12/26 20:54:44

Thread类的常用结构

构造器

  • public Thread():分配一个新的线程对象。
  • public Thread(String name):分配一个指定名字的新的线程对象。
  • public Thread(Runnable target):指定创建线程的目标对象,它实现了Runnable接口中的run()方法。
  • public Thread(Runnable target,String name):分配一个带有指定目标新的线程对象并指定名字。

常用方法系列1

  • public void run():此线程要执行的任务在此处定义代码。
  • public void start():导致此线程开始执行;Java虚拟机调用此线程的run方法。
  • public String getName():获取当前线程名称。
  • public void setName():设置该线程名称。
  • public static Thread currentThread():返回对当前正在执行的线程对象的引用。在Thread子类中就是this,通常用于主线程和Runnable实现类。
  • public static void sleep(long millis):使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行)。
  • public static void yield(): yield只是让当前线程暂停一下,让系统的线程调度器重新调度一次,希望优先级与当前线程相同或更高的其他线程能够获得执行机会,但是这个不能保证,完全有可能的情况是,当某个线程调用了yield方法暂停之后,线程调度器又将其调度出来重新执行。

常用方法系列2

  • public final boolean isAlive(): 测试线程是否处于活动状态。如果线程已经启动且尚未终止,则为活动状态。

  • void join(): 等待该线程终止。

    void join(long millis): 等待该线程终止的时间最长为millis毫秒。如果millis时间到,将不再等待。

    void join(long millis,int nanos): 等待该线程终止的时间最长为millis毫秒 + nanos 纳秒。

  • public final void stop(): 已过时,不建议使用。强行结束一个线程的执行,直接进入死亡状态。run()即刻停止,可能会导致一些请理性的工作得不到完成,如文件,数据库等的关闭。同时,会立即释放该线程所持有的所有的锁,导致数据得不到同步的处理,出现数据不一致的问题。

  • void suspend() / void resume(): 这两个操作就好比播放器的暂停和恢复。二者必须成对出现,否则非常容易发生死锁。suspend()调用会导致线程暂停,但不会释放任何锁资源,导致其他线程都无法访问被它占用的锁,直到调用resume()。已过时,不建议使用。

常用的方法系列3

每个线程都有一定的优先级,同优先级线程组成先进先出队列(先到先服务),使用分时调度策略。优先级高的线程采用抢占式策略,获得较多的执行机会。每个线程默认的优先级都与创建它的父线程具有相同的优先级。

  • Thread类的三个优先级常量:
    • MAX_PRIORITY(10):最高优先级
    • MIN_PRIORITY(1): 最低优先级
    • NORM_PRIORITY(5):普通优先级,默认情况下main线程具有普通优先级。
  • public final int getPriority(): 返回线程优先级
  • public final void setPriority(int newPriority): 改变线程的优先级,范围在[1——10]之间。

练习:获取main线程对象的名称和优先级。

声明一个匿名内部类继承Thread类,重写run方法,在run方法中获取线程名称和优先级。设置该线程优先级为最高优先级并启动该线程。

一、线程的常用结构
1. 线程中的构造器
- public Thread():分配一个新的线程对象。
- public Thread(String name):分配一个指定名字的新的线程对象。
- public Thread(Runnable target):指定创建线程的目标对象,它实现了Runnable接口中的run()方法。
- public Thread(Runnable target,String name):分配一个带有指定目标新的线程对象并指定名字。


2.线程中的常用方法:
> start():1)启动线程 (2)调用线程的run()
> run(): 将线程要执行的操作,声明在run()中。
> currentThread(): 获取当前执行代码对应的线程。
> getName(): 获取线程名
> setName(): 设置线程名
> sleep(long millis): 静态方法,调用时,可以使得当前线程睡眠指定的毫秒数
> yield(): 静态方法,一旦执行此方法,就释放CPU的执行权
> join(): 在线程a中通过线程b调用join(),意味着线程a进入阻塞状态,直到线程b执行结束,线程a才结束阻塞状态,继续执行
> isAlive(): 判断当前线程是否还存活


过时方法:
> stop(): 强行结束一个线程的执行,直接进入死亡状态。不建议使用
> void suspend() / void resume() : 可能造成死锁,所以也不建议使用



3.线程的优先级:
getPriority(): 获取线程的优先级
setPriority(): 设置线程的优先级。范围是[1,10]

Thread类内部声明的三个常量:
- MAX_PRIORITY(10):最高优先级
- MIN_PRIORITY(1): 最低优先级
- NORM_PRIORITY(5):普通优先级,默认情况下main线程具有普通优先级。


二、线程的生命周期

常用方法练习:

package thread.demo02;

public class EvenNumberTest {
    public static void main(String[] args) {
        //测试1
        PrintNumber t1 = new PrintNumber("线程1:偶数");
        t1.setName("线程1(修改):偶数");//修改上面的线程名"线程1:偶数"为"线程1(修改):偶数"
        t1.setPriority(Thread.MAX_PRIORITY);//注意不是哪个优先级高就先运行完哪个线程,是CPU几率更高优先来调用优先级高的线程。
        // 打印出来发现还是主线程第一个运行,因为现在都是多核CPU,这是概率问题。
        t1.start();

        //测试setName()
        Thread.currentThread().setName("主线程");
        Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
        for (int i = 1; i <= 100; i++) {
            if (i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + " 优先级为:" +
                        Thread.currentThread().getPriority() + ": " + i);
            }

//            if (i == 20){
//                try {
//                    t1.join();
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }

        }

        //测试isAlive()
//        System.out.println("线程1(修改):偶数 是否存活?" + t1.isAlive());

        //测试2
        PrintNumber1 p = new PrintNumber1();
        Thread t2 = new Thread(p,"线程2:奇数");
        t2.start();

    }
}

//测试1:-public Thread(String name):分配一个指定名字的新的线程对象。
class PrintNumber extends Thread{

    //无参构造
    public PrintNumber(){

    }
    //分配一个指定名字的新的线程对象。
    public PrintNumber(String name){
        super(name);
    }

    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {

            //测试sleep()
//            try {
//                Thread.sleep(1000);//设置了1000毫秒也就是一秒,对应的这个线程1一秒钟执行一下,直到结束
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }

            if (i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + " 优先级为:" +
                        Thread.currentThread().getPriority() + ": " + i);
            }

            //测试yield()
//            if (i % 20 == 0){
//                Thread.yield();
//            }

        }
    }
}

//测试2:- public Thread(Runnable target,String name):分配一个带有指定目标新的线程对象并指定名字。
class PrintNumber1 implements Runnable{

    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            if (i % 2 != 0){
                System.out.println(Thread.currentThread().getName() + " 优先级为: " +
                        Thread.currentThread().getPriority() + " " + i);
            }
        }
    }
}

多线程的生命周期

Java语言使用Thread类及其子类的对象来表示线程,在它的一个完整的生命周期中通常要经历如下一些状态:

JDK1.5之前:5种状态

线程的生命周期有五种状态:新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)、死亡(Dead)。CPU需要在多条线程之间切换,于是线程状态会多次在运行、阻塞、就绪之间切换。

在这里插入图片描述

1.新建

当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态。此时它和其他Java对象一样,仅仅由JVM为其分配了内存,并初始化了实例变量的值。此时的线程对象并没有任何线程的动态特征,程序也不会执行它的线程体run()。

2.就绪

但是当线程对象调用了start()方法之后,就不一样了,线程就从新建状态转为就绪状态。JVM会为其创建方法调用栈和程序计数器,当然,处于这个状态中的线程并没有开始运行,只是表示已具备了运行的条件,随时可以被调度。至于什么时候被调度,取决于JVM里线程调度器的调度。

注意:
程序只能对新建状态的线程调用start(),并且只能调用一次,如果对非新建状态的线程,如已启动的线程或已死亡的线程调用start()都会报错IllegalThreadStateException异常。

3.运行

如果处于就绪状态的线程获得了CPU资源时,开始执行run()方法的线程体代码,则该线程处于运行状态。如果计算机只有一个CPU核心,在任何时刻只有一个线程处于运行状态,如果计算机有多个核心,将会有多个线程并行(Parallel)执行。

4.阻塞

当在运行过程中的线程遇到如下情况时,会让出CPU并临时中止自己的执行,进入阻塞状态:

  • 线程调用了sleep()方法,主动放弃所占用的CPU资源;
  • 线程试图获取一个同步监视器,但该同步监视器正被其他线程持有;
  • 线程执行过程中,同步监视器调用了wait(),让它等待某个通知(notify);
  • 线程执行过程中,同步监视器调用了wait(time);
  • 线程执行过程中,遇到了其他线程对象的加塞(join);
  • 线程被调用suspend方法被挂起(已过时,因为容易发生死锁);

当前正在执行的线程被阻塞后,其他线程就有机会执行了。针对如上情况,当发生如下情况时会解除阻塞,让该线程重新进入阻塞状态,等待线程调度器再次调度它:

  • 线程的sleep()时间到;
  • 线程成功获得了同步监视器;
  • 线程等到了通知(notify);
  • 线程wait的时间到了
  • 加塞的线程结束了;
  • 被挂起的线程又被调用了resume恢复方法(已过时,因为容易发生死锁);

5.死亡

线程会以以下三种方式之一结束,结束后的线程就处于死亡状态:

  • run()方法执行完成,线程正常结束
  • 线程执行过程中抛出了一个未捕获的异常(Exception)或错误(Error)
  • 直接调用该线程的stop()来结束该线程(已过时)

JDK1.5及之后:6种状态

在java.lang.Thread.State的枚举类中这样定义:

public enum State {
    NEW,
    RUNNABLE,
    BLOCKED,
    WAITING,
    TIMED_WAITING,
    TERMINATED;
}

下图中在JAVA基础阶段暂时了解一下,不去看里面具体方法,以后在JUC里面再看

在这里插入图片描述

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

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

相关文章

Python实现温度植被干旱指数(TVDI)的计算

前言 温度植被干旱指数&#xff08;Temperature Vegetation Dryness Index&#xff0c;TVDI&#xff09;是一种基于光学与热红外遥感通道数据进行植被覆盖区域表层土壤水分反演的方法。作为同时与归一化植被指数(NDVI)和地表温度(LST)相关的温度植被干旱指数(TVDI)可用于干旱监…

第二十五节:通信之WLAN(WiFi聚合)

欢迎大家一起学习探讨通信之WLAN。为了减少帧交互中额外资源占用开销&#xff0c;提高WiFi网络系统整体运行效率&#xff0c;802.11n协议引入定义了聚合功能。本节将基于协议定义内容和实例&#xff0c;详细分析“A-MSDU"和“A-MPDU”两种聚合功能。 关键字 S1G(Sub 1 GH…

linux0.12-10-6-tty_io.c

[539页] 10-6 tty_io.c程序 10-6-1 功能描述 每个tty设备有3个缓冲队列&#xff0c;分别是读缓冲队列(read_q)、写缓冲队列(write_q)和辅助缓冲队列(secondary)&#xff0c;定义在tty_struct结构中(include/linux/tty.h)。 对于每个缓冲队列&#xff0c;读操作是从缓冲队列的…

数据可视化:部分整体类可视化图表大全

图表是处理数据的重要组成部分&#xff0c;因为它们是一种将大量数据压缩为易于理解的格式的方法。数据可视化可以让受众快速Get到重点。 数据可视化的图表类型极其丰富多样&#xff0c;而且每种都有不同的用例&#xff0c;通常&#xff0c;创建数据可视化最困难的部分是确定哪…

冯诺依曼体系结构详解

一.冯诺伊曼体系结构的概念&#xff1a; 约翰冯诺依曼&#xff08;John von Neumann&#xff0c;1903.1.28-1957.2.8&#xff09;&#xff0c;美籍匈牙利数学家&#xff0c;计算机科学家&#xff0c;物理学家。是20世纪最重要的数学家之一&#xff0c;后来被称为计算机之父。 后…

计算机网络学习笔记-网络层

目录 概述 提供的两种服务&#xff1a;面向连接的虚电路、不面向连接的数据报 对比 虚拟互连网络 地址解析协议 ARP 主要作用 使用过程 位置 因特网控制报文协议 ICMP 作用 位置 种类 差错报告报文&#xff1a;终点不可达、源点抑制、时间超过、参数问题、改变路由…

【HMS Core】【ML Kit】活体检测FAQ合集

【问题描述1】 使用示例代码集成活体检测SDK时&#xff0c;报错state code -7001 【解决方案】 使用示例代码前请详细阅读示例工程中的“README”文件。您需要完成以下操作后才可以运行示例代码。 在AppGallery Connect网站下载自己应用的“agconnect-services.json”文件&a…

kaggle新赛推荐 | 从游戏中预测学生的表现

赛题名称&#xff1a;Predict Student Performance from Game Play 从游戏中预测学生的表现 赛题链接&#xff1a;https://www.kaggle.com/competitions/predict-student-performance-from-game-play 赛题背景 学习意味着有趣&#xff0c;这就是基于游戏的学习的用武之地。这…

Java大型货运系统源码(司机APP端+货主APP端)

技术架构&#xff1a;spring boot、mybatis、redis、vue、element-ui 开发语言&#xff1a;java 开发工具&#xff1a;idea、vscode、hbuilder 前端框架&#xff1a;vue 后端框架&#xff1a;spring boot 数 据 库&#xff1a;mysql 移 动 端&#xff1a;uniapp混合开发原…

数据结构与算法(七)

二叉树 如果说树中的每个结点最多只能有两个子结点&#xff0c;这样的树我们就称为二叉树&#xff0c;二叉树可以为空。 特点: 每个结点最多有两棵子树&#xff0c;所以二叉树中不存在度大于二的结点棵树中&#xff0c;最大的结点的度称为树的度&#xff0c;结点的度:结点所…

Git 分支相关操作

1 创建一个分支 Create a new directory and initialize a Git repository. We are going to create a directory named “tutorial”. $ mkdir tutorial $ cd tutorial $ git init Initialized empty Git repository in /Users/eguchi/Desktop/tutorial/.git/进入这个tutori…

一篇文章全面了解光分路器、PLC分路器、拉锥分路器

光纤分路器 光纤分路器&#xff0c;又称为分光器&#xff0c;是将一根光纤信号按照既定的比例分解为两路或多路光信号输出&#xff0c;是接入FTTH方式的光无源器件。 例如&#xff0c;一个1x4光分路器就是将一根光纤中的光信号按照一定的比例分配给四根光纤。与WDM系统的波分复…

【Java入门】运算符

前言 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff0c;喜爱音乐的一位博主。 &#x1f4d7;本文收录于Java入门篇系列&#xff0c;该专栏主要讲解&#xff1a;什么是java、java的数据类型与变…

放大镜-第14届蓝桥杯省赛Scratch中级组真题第3题

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第138讲。 放大镜&#xff0c;本题是2023年5月7日举行的第14届蓝桥杯省赛Scratch图形化编程中级组编程第3题&#xff0…

MAC环境下使用 xray 工具

这里不做过多介绍&#xff0c;下面链接讲的非常清楚&#xff0c;下面记录一下遇到的坑。 https://docs.xray.cool/#/tutorial/webscan_basic_crawler Mac环境下选择对应的工具 下载完以后&#xff0c;放入自己的目录下&#xff0c;打开终端查看版本信息 ./xray_darwin_amd64 v…

Jupyter程序安装和使用指南【操作示例】

Jupyter Notebook(简称Jupyter)是一个交互式编辑器&#xff0c;它支持运行40多种编程语言&#xff0c;便于创建和共享文档。Jupyter本质上是一个Web应用程序&#xff0c;与其他编辑器相比&#xff0c;它具有小巧、灵活、支持实时代码、方便图表展示等优点。下面分别为大家演示如…

在CTEX文档生成中使用WinEit编辑带有公式符号的中文文档应用举例

CTEX文档生成中使用WinEit编辑带有公式符号的中文文档应用举例 CTEX在编辑文档格式和排版时具有优秀的性能&#xff0c;可批量处理文档格式&#xff0c;该用格式时候也非常快捷。下面举例介绍CTEX文档生成中怎样使用WinEit编辑带有公式符号的中文文档。 1.需要的代码 .在WinEi…

IT入门深似海,入门到放弃你学废了嘛

我一直觉得IT行业 程序员行业。甚至觉得程序员人群 是一个特殊存在的群体。 入门到放弃&#xff0c;是真的&#xff0c;IT门槛高嘛。 其实吧&#xff0c;IT编程门槛&#xff0c;是有的&#xff0c;但是对于感兴趣的&#xff0c;想学习IT编程同学来说&#xff0c;也是一件容易事…

Few-Shot Knowledge Graph Completion

[1911.11298] Few-Shot Knowledge Graph Completion (arxiv.org) 目录 Background Model Encoding Heterogeneous Neighbors Aggregating Few-Shot Reference Set Matching Query and Reference Set Matching Query and Reference Set Background 以往的KGC认为每个关系…

【微信小程序】微信小程序集成高德卫星地图完成多边形绘制与截图保存

目录 功能需求 使用的技术点 注意点 实现步骤 代码 微信小程序-地图所在的wxml 微信小程序-地图所在的js 微信小程序-展示截图结果的wxml 微信小程序-展示截图结果的js H5-地图所在的html 完成效果 感谢阅读&#xff0c;欢迎讨论 功能需求 打开页面展示卫星地图&…