【JavaEE】Thread的方法和属性

文章目录

  • 1、Thread的常见构造方法
  • 2、Thread的几个常见属性
    • 2.1 ID
    • 2.2 名称
    • 2.3 状态
    • 2.4 优先级
    • 2.5 是否后台线程
    • 2.6 是否存活
    • 2.7 是否被中断
  • 3.补充说明
    • 3.1 Thread.sleep()的作用
    • 3.2 Thread.sleep()的异常处理方式


1、Thread的常见构造方法

方法说明
Thread()创建线程对象
Thread(Runnable target)使用Runnable对象创建线程对象
Thread(String name)创建线程对象,并命名
Thread(Runnable target, String name)使用Runnable对象创建线程对象,并命名
Thread(ThreadGroup, Runnable target)线程可以被用来分组管理,分好组即可

前面两个构造方法我们在线程的概念这篇中已经讲过了,这里就不在过多赘述
创建线程对象,并命名和使用Runnable对象创建对象,并命名
举例:

public class Test6 {
    public static void main(String[] args) {
        Thread thread = new Thread(()->{
            while (true) {
                System.out.println("hello");               
            }
        },"自定义线程");
        thread.start();        
    }
}

这里我们也可以通过jconsole.exe这个应用程序来观察到
在这里插入图片描述
注意:这么没有看到main线程不是main线程没有被创建,而是执行太快,已经执行完毕了
最后一个构造方法,在开发中很少用到,这里不再过多讨论

2、Thread的几个常见属性

属性获取方法
IDgetId()
名称getName()
状态getState()
优先级getPriority()
是否后台线程isDaemon()
是否存活isAlive()
是否被中断isInterrupted()

2.1 ID

ID是线程的唯一标识,不同线程不会重复,这里的ID和系统中PCB上的ID是不同的

2.2 名称

名称是各种调试工具用到

2.3 状态

状态表示线程当前所处的一个情况,后续会再次说明

2.4 优先级

优先级高的线程理论上来说更容易被调度

2.5 是否后台线程

线程有前台线程和后台线程
前台线程:这样的线程如果不运行结束,Java进程是一定不会结束的
前台线程可以有多个,多个前台线程,必须最后一个前台线程结束,进程才可以结束
后台线程:这样的线程,即使继续执行,也不能阻止Java进程结束

在Java代码中,main线程是前台线程,程序员创建出来的线程在默认情况下都是前台线程,我们可以通过setDaemon方法把线程设置为后台线程
举例:

public class Test7 {
    public static void main(String[] args) {
        Thread thread = new Thread(()->{
            for (int i = 0; i < 5; i++) {
                System.out.println("hello thread");                
            }
        });
        //设置为后台线程
        thread.setDaemon(true);
        thread.start();
    }
}

运行结果:
在这里插入图片描述
此时,进程中只有main是前台线程,只要main结束,整个进程就结束了,main执行完start立即结束
此时thread还没来得及打印,进程就结束了,里面的线程也就结束了

注意:这里也有一定的概率,出现thread打印一次,然后结束进程的情况,这个就要看main先执行结束,还是thread先执行一次打印(线程之间是抢占式执行,调度顺序不确定)
判断是否为后台线程:

public class Test7 {
    public static void main(String[] args) {
        Thread thread = new Thread(()->{
            for (int i = 0; i < 5; i++) {
                System.out.println("hello thread");                
            }
        });
        //设置为后台线程
        thread.setDaemon(true);
        thread.start();
        //是后台线程返回true,不是返回false
        System.out.println(thread.isDaemon());
    }
}

运行结果:
在这里插入图片描述

2.6 是否存活

指的是系统中的线程(PCB)是否存在
Thread对象的生命周期和PCB的生命周期是不一定完全一样的
举例:

public class Test8 {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(()->{
            System.out.println("hello thread");           
        });
        //如果PCB存活返回true,不存活返回false       
        System.out.println(thread.isAlive());
    }
}

运行结果:
在这里插入图片描述
只有调用thread.start()方法后,才会创建线程,PCB才会在内核中创建出来
代码如下:

public class Test8 {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(()->{
            System.out.println("hello thread");           
        });
        thread.start();
        System.out.println(thread.isAlive());
    }
}

在这里插入图片描述

2.7 是否被中断

在Java中,我们可以通过调用Thread类的interrupt()方法来终止线程,这会向线程发送一个中断信号,线程可以通过检查isInterrupted()方法来响应中断并做出相应的处理,通常是安全的终止线程的执行
举例:

public class Test11 {
    public static void main(String[] args) {
        Thread thread = new Thread(()->{
            //currentThread()这是一个static方法,能获取到当前线程,获取到thread这个引用
            //isInterrupte()线程内置的标志位 boolean变量 true表示线程终止 false表示线程继续执行
            while(!Thread.currentThread().isInterrupted()) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();                    
                }
            }
        });
        thread.start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //中断thread线程
        thread.interrupt();
    }
}

运行结果:
在这里插入图片描述
注意这里,即使将thread线程中断了,但是循环还在继续执行,这个是为什么?
thread.interrupt();这段代码干了两件事:
1.将Thread.currentThread().isInterrupted()的布尔值改变为true
2.立即唤醒sleep(),不在等待

sleep()被唤醒的同时,就会清除刚才的标志位(又改回false),从而导致代码中的循环继续执行,同时catch()方法中的代码也会执行

之所以要改回来就是把控制权交给程序员,让程序员自己在catch()方法中设置,假如要中断thread线程,只需要在catch()方法中写break;就可以中断循环,使thread线程结束

3.补充说明

3.1 Thread.sleep()的作用

sleep()这个方法指睡眠/休眠,就是让线程主动进入“阻塞状态”(PCB上的状态属性),主动放弃去cpu上执行,时间到了,就会解除阻塞状态重新被调度到cpu上执行

3.2 Thread.sleep()的异常处理方式

**在main方法中处理sleep异常的方式有两种:
1.throws **

public class Test {
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(1000);
    }
}

2.try catch

public class Test {
    public static void main(String[] args) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

如果是在线程的run方法中只能用:try catch

public class Test {
    public static void main(String[] args) {
        Thread thread = new Thread(()-> {
            System.out.println("hello thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
    }
}

这是因为throws也是方法签名的一部分,在run方法重写的时候,就要求方法的签名要一样
method sign ature包含:1.方法的名字
2.方法的参数列表(包含了类型和个数)
3.声明抛出的异常

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

动态规划-子序列问题1

文章目录 1. 最长递增子序列&#xff08;300&#xff09;2. 摆动序列&#xff08;376&#xff09;3. 最长递增子序列的个数&#xff08;673&#xff09;4. 最长数对链&#xff08;646&#xff09; 1. 最长递增子序列&#xff08;300&#xff09; 题目描述&#xff1a; 状态表…

Linux 进程间通信之命名管道

&#x1f493;博主CSDN主页:麻辣韭菜&#x1f493;   ⏩专栏分类&#xff1a;Linux知识分享⏪   &#x1f69a;代码仓库:Linux代码练习&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多Linux知识   &#x1f51d; 目录 前言 命名管道 创建一个命名管道 …

LeetCode题练习与总结:删除排序链表中的重复元素--83

一、题目描述 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,1,2] 输出&#xff1a;[1,2]示例 2&#xff1a; 输入&#xff1a;head [1,1,2,3,3] 输…

袁庭新ES系列17节|Spring Data Elasticsearch基础

前言 为了简化对Elasticsearch的操作Spring Data提供了Spring Data Elasticsearch。Spring Data Elasticsearch是Spring Data技术对Elasticsearch原生API封装之后的产物&#xff0c;它通过对原生API的封装&#xff0c;使得程序员可以简单的对Elasticsearch进行各种操作。接下来…

InfluxDB安装使用介绍

1.介绍 InfluxDB是一个由InfluxData开发的开源时序型数据。它由Go写成&#xff0c;着力于高性能地查询与存储时序型数据。InfluxDB被广泛应用于存储系统的监控数据&#xff0c;IoT行业的实时数据等场景。 2.对常见关系型数据库&#xff08;MySQL&#xff09;的基础概念对比 1…

满上! —— 十年之约#22(ROI 48%)

原创 | 刘教链 空头在忍耐了很久之后&#xff0c;趁五一劳动节东方放假发动突袭&#xff0c;把BTC&#xff08;比特币&#xff09;打到6万刀以下。这使得我们终于终结了7个月七连涨的趋势&#xff0c;确定4月以收跌结束。 4月开盘70k&#xff0c;最高72.8k&#xff0c;最低59.6…

CPU卡园区码分析计算,根据卡号计算外部密码

生活中我们可能遇到这种情况&#xff0c;比如家里的门禁卡丢失了&#xff0c;拿着家里人的去街上 复制&#xff0c;结果对方说无法复制&#xff0c;因为这种卡是CPU卡的一种&#xff0c;必须知道园区码才可以成功复制&#xff0c;这个时候&#xff0c;我们就需要请出我们的战神…

uniapp实现点击事件跳转页面

首先定义一个点击事件 这里采用的vue3的写法&#xff0c;然后写上触发事件后要跳转的路径 function jump() {uni.switchTab({url:/pages/bangong/index})} 到这里就简单的实现uniapp的点击跳转页面了

开源农场管理软件

软件介绍 Tania是一款基于Go、Vue.JS和SQLite的开源农场日记软件。该项目始于2016年11月&#xff0c;由于无法找到适合自己需求的软件&#xff0c;开发团队决定自己搭建一套适合家庭后院花园的管理系统&#xff0c;并可以随时随地进行管理。 项目功能描述 Tania是一款免费且开源…

密码学基础练习五道 RSA、elgamal、elgamal数字签名、DSA数字签名、有限域(GF)上的四则运算

1.RSA #include <stdlib.h>#include <stdio.h>#include <string.h>#include <math.h>#include <time.h>#define PRIME_MAX 200 //生成素数范围#define EXPONENT_MAX 200 //生成指数e范围#define Element_Max 127 //加密单元的…

Java基础知识(三) -- 流程控制

不论哪种编程语言&#xff0c;都会提供两种基本的流程控制结构&#xff1a;分支结构和循环结构。其中分支结构用于实现根据条件来选择性地执行某段代码&#xff0c;循环结构则用于实现根据循环条件重复执行某段代码。 1. 顺序结构 任何编程语言中最常见的程序结构就是顺序结构…

van-cascader(vant2)异步加载的bug

问题描述&#xff1a;由于一次性返回所有的级联数据的话&#xff0c;数据量太大&#xff0c;接口响应时间太久&#xff0c;因此采用了异步加载的方案&#xff0c;看了vant的官方示例代码&#xff0c;照着改了下&#xff0c;很轻松地实现了功能。正当我感叹世界如此美好的时候&a…

结合创新!频域+时间序列,预测误差降低64.7%

频域时间序列不仅能提供更丰富的信息&#xff0c;还能提高模型性能和预测准确性。对于论文er来说&#xff0c;是个可发挥空间大、可挖掘创新点多的研究方向。 具体来说&#xff1a; 通过将复杂的时间序列数据转换成简单的频率成分&#xff0c;我们可以更容易地捕捉到数据的周期…

【SpringBoot整合系列】SpringBoot整合Redis[附redis工具类源码]

目录 SpringBoot整合Redis1.下载和安装Redis2.新建工程&#xff0c;导入依赖3.添加配置4.先来几个基本的示例测试代码输出结果用redis客户端查看一下存储内容 5.封装redis工具类RedisKeyUtilRedisStringUtilRedisHashUtilRedisListUtilRedisSetUtilRedisZsetUtil备注 6.测试通用…

nginx--第三方模块安装上传下载服务

第三方模块安装 准备 cd /usr/local/src/ yum install git -y git clone https://github.com/openresty/echo-nginx-module.git cd nginx-1.24.0 yum -y install perl-devel perl-ExtUtils-Embed zlib-devel gcc-c libtool openssl openssl-devel 编译安装 ./configure \--p…

Javascript:Web APIs(一)

Javascript基础&#xff08;一&#xff09; Javascript基础&#xff08;二&#xff09; Javascript基础&#xff08;三&#xff09; Javascript基础已经结束&#xff0c;接下来我们将进入到整个Web API学习中&#xff0c;在此&#xff0c;我们将学习DOM操作&#xff0c;基本的…

32.Docker认识

Docker介绍 Docker是一个快速交付应用&#xff0c;运行应用的技术。 1.可以将程序、依赖、运行环境一起打包为一个镜像&#xff0c;可以迁移到任意Linux操作系统。 2.运行时利用沙箱机制行程隔离容器&#xff0c;各个应用互不干扰。 3.启动、移除都可以通过一行命令完成&am…

多线程基础知识(全面):创建线程、线程状态如何变化、wait()、notify()、sleep()、停止线程

文章目录 一、创建线程的四种方式1.1 继承Thread类1.2 实现runnable接口1.3 实现Callable接口1.4 线程池创建线程1.5 补充&#xff1a;runnable、callable都可以创建线程&#xff0c;有什么区别&#xff1b;run()和 start()有什么区别 二、线程包括哪些状态、状态之间如何变化2…

40.WEB渗透测试-信息收集-域名、指纹收集(2)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;39.WEB渗透测试-信息收集-域名、指纹收集&#xff08;1&#xff09; oneforall的安装前置…

《深入解析Windows操作系统》第5章节学习笔记

1、每个Windows进程都是由一个执行体进程EPROCESS结构来表示的&#xff0c;EPROCESS和相关数据结构位于系统空间&#xff0c;但是进程环境控制块PEB是个例外&#xff0c;它位于进程空间地址中&#xff08;因为它包含了一些需要由用户模式代码来修改的信息&#xff09;。对于每一…