线程的创建和使用(二)

1、线程的类和方法

Thread类是JVM用来管理线程的一个类,换句话说,每个线程都有唯一一个的Thread对象与之关联。

1.1、Thread的常见方法

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

Thread t1=new Thread();

Thread t2=new Thread(new MyRunnable());

Thread t3=new Thread("线程的名字");

Thread t4=new Thread(new MyRunnable(),"线程的名字");

 1.2、Thread的几个常见属性

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

Thread类是JAVA中的类,我们通过java代码创建Thread对象是java中的对象,调用start方法后,通过JVM去申请操作系统中的线程PCB,线程的对象是与PCB是一一对应的关系,但是他们的生命周期是不同的。

2、示例

2.1、后台线程的演示


public class Exe_02 {
    public static void main(String[] args) {
        //创建一个线程
        Thread thread=new Thread(()->{
            while(true){
                System.out.println("你干嘛,哎呦");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        //设置成后台线程
        thread.setDaemon(true);
        //启动线程
        thread.start();
        //查看线程是否存活
        System.out.println("是否存活"+thread.isAlive());
        System.out.println("main方法执行完成");
    }
}

设置为后台线程时,mian方法执行完成之后,,整个线程就退出了

1、线程在创建的时候,默认是一个前台线程

2、前台线程是可以组织线程退出的

3、后台线程不阻止影响进程的退出

2.2、线程是否存活


/**
 * 演示线程是否存活
 */
public class Exe_03 {
    public static void main(String[] args) throws InterruptedException {
        //创建线程
        Thread thread=new Thread(()->{
           int count=0;
           while(true) {
               System.out.println("小黑子" + count++);
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               //运行五次退出
               if(count>=5){
                   break;
               }
           }
        });
        //启动之前查看是否存活
        System.out.println("启动之前是否存活->"+thread.isAlive());
        //启动线程
        thread.start();
        //等待一秒让系统创建线程,确保线程创建完成开始执行
        Thread.sleep(1000);
        System.out.println("启动之后是否存活"+thread.isAlive());
        //等待线程执行完成
        thread.join();
        System.out.println("线程执行完成是否存活"+thread.isAlive());
    }
}

 2.3、线程的各个属性


/**
 * 线程的属性
 */
public class Exe_04 {
    public static void main(String[] args) {
        Thread thread=new Thread(()->{
            while(true){
                System.out.println("hello,iKun");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"鸽鸽");
        //启动线程
        thread.start();
        System.out.println("线程id="+thread.getId());
        System.out.println("线程名="+thread.getName());
        System.out.println("进程状态="+thread.getState());
        System.out.println("进程优先级="+thread.getPriority());
        System.out.println("线程是否后台="+thread.isDaemon());
        System.out.println("线程是否存活="+thread.isAlive());
        System.out.println("线程是否中断="+thread.isInterrupted());
    }
}

 2.4、start()和run()方法的区别

分别调用这两个方法的现象?

start()方法:它调用系统API,去申请一个系统层面的PCB,也就是说真正的申请系统的线程。

run()方法:是在描述线程中具体要执行的任务。

*单独调用run方法,只是对一个普通的java对象的普通方法调用而已,跟String的equals()方法一样,它并没有真正的去启动一个线程。

/*
start()方法是真正意义上调用系统API,申请系统层面的PCB,申请了系统创建线程的资源,真正创建了线程,可以进行多线程的调用
run()描述了线程任务,并不能进行多线程的调用,就跟普通的方法是一样的
 */
public class Exe_05 {
    public static void main(String[] args) throws InterruptedException {
        Thread thread=new Thread(()->{
           while(true){
               System.out.println("只因坤坤爱坤坤");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });
        thread.start();
        //调用run方法
        thread.run();
        //主线程打印一句话
        while(true){
            System.out.println("main");
            Thread.sleep(1000);
        }
    }
}

 2.5、线程中断

线程执行一半的时候需要停下来,提前结束。

目前常见的有以下两种方式:
1. 通过共享的标记来进行沟通
2. 通过thread调用 interrupted() 方法来通知

方式一:


/**
 * 通过标志位完成线程中断
 */
public class Exe_06 {
    //设置标志符
    private static Boolean isQuit=false;
    public static void main(String[] args) throws InterruptedException {
        Thread thread=new Thread(() ->{
            //每次执行都要判断是否中断标志位
            while(!isQuit){
                System.out.println("再多一眼看一眼就会爆炸");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("线程执行完成");
        });
        System.out.println("线程启动前的状态="+thread.getState());
        System.out.println("线程启动前是否存活="+thread.isAlive());
        //启动线程
        thread.start();
        System.out.println("线程启动后的状态="+thread.getState());
        System.out.println("线程启动后是否存活="+thread.isAlive());
        //等待5秒
        Thread.sleep(4000);
        //修改标志位
        isQuit=true;
        Thread.sleep(4000);
        System.out.println("线程中断之后的状态="+thread.getState());
        System.out.println("线程中断之后是否存活="+thread.isAlive());
    }
}

 方式二:


public class Exe_07 {
    public static void main(String[] args) throws InterruptedException {
        Thread thread=new Thread(() ->{
            //判断当前线程内部维护的中断标识
            while(Thread.currentThread().isInterrupted()){
                System.out.println("练习时长两年半");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    //中断唤醒线程睡眠状态,会抛出异常
                    //处理中断逻辑
                    //方式一;什么也不干,不去理会
                    //方式二:一会处理
                    //方式三:真正的中断操作
                    break;
                }
            }
            System.out.println("线程执行完成");
        });
        //启动线程
        thread.start();
        System.out.println("启动之前线程状态"+thread.getState());
        System.out.println("启动之前是否存活"+thread.isAlive());
        //先让这个线程执行一会
        Thread.sleep(3000);
        //中断线程
        thread.isInterrupted();//调用本地方法让PCB完成中断
        //等待线程销毁
        Thread.sleep(3000);
        System.out.println("中断之后线程状态"+thread.getState());
        System.out.println("中断之后是否存活"+thread.isAlive());
    }
}

调用Interrupted()方法后,会有两种情况注意:

1、线程正在RUNNABLE状态,那么不抛出异常,会直接中断。

2、线程在TIMED_WAITING状态,这时线程被唤醒配置并抛出异常,那么处理逻辑就要以catch语句块进行处理

3、处理中断能否正确执行,有两个地方需要判断,一个式while循环条件,处理情况1,异常中处理情况2。

2.6、线程等待


public class Exe_08 {
    public static void main(String[] args) {
        //创建线程
        Thread thread=new Thread(() ->{
            for (int i = 0; i < 5; i++) {
                System.out.println("hello,thread!!!");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("线程执行完成!");
        });
        //启动线程
        thread.start();
        System.out.println("join之前线程状态" + thread.getState());
        System.out.println("join之前是否存活" + thread.isAlive());
        //使用join等待thread线程结束
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("join之后线程状态" + thread.getState());
        System.out.println("join之后是否存活" + thread.isAlive());
        System.out.println("主线程执行完成!!");
    }
}

 2.7、休眠当前线程

 2.8、获取当前线程

方法说明
public static Thread currentThread();返回当前线程对象的引用

3、线程的状态

线程的状态是一个枚举类型 Thread.State

*NEW: 安排了工作, 还未开始行动
*RUNNABLE: 可工作的. 又可以分成正在工作中和即将开始工作.
*BLOCKED: 这几个都表示排队等着其他事情
*WAITING: 这几个都表示排队等着其他事情
*TIMED_WAITING: 这几个都表示排队等着其他事情
*TERMINATED: 工作完成了.

 

 

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

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

相关文章

Python中对基本文件操作

1.文件的作用 保存数据放在磁盘中 2.打开文件 fopen(‘文件’,‘w’)或者fopen(‘文件’,‘r’) 3.文件操作 3.1 写数据(write) 如果文件不存在那么创建&#xff0c;如果存在那么就先清空&#xff0c;然后写入数据 对象open(“文件”,w) 对象.write&#xff08;“写入数…

【数据结构与算法】04 哈希表 / 散列表 (哈希函数、哈希冲突、链地址法、开放地址法、SHA256)

一种很好用&#xff0c;很高效&#xff0c;又一学就会的数据结构&#xff0c;你确定不看看&#xff1f; 一、哈希表 Hash Table1.1 核心概念1.2 哈希函数 Hash Function1.3 哈希冲突 Hash Collision1.4 哈希冲突解决1.41 方法概述1.42 链地址法 Separate Chaining1.43 开放寻址…

C语言学习笔记:指针

✨博文作者&#xff1a;烟雨孤舟 &#x1f496; 喜欢的可以 点赞 收藏 关注哦~~ ✍️ 作者简介: 一个热爱大数据的学习者 ✍️ 笔记简介&#xff1a;作为大数据爱好者&#xff0c;以下是个人总结的学习笔记&#xff0c;如有错误&#xff0c;请多多指教&#xff01; 目录 简介 …

企业会计软件必备!深入了解为何选择会计软件以及其带来的好处

随着科技的发展&#xff0c;企业需要更加智能化和数字化的财务管理方式&#xff0c;因此会计软件是现代社会的必然产物&#xff0c;会计软件可以帮助企业更有效地进行财务管理。 企业为什么需要会计软件&#xff1f; 提高准确度 通过传统的手工操作财务记录&#xff0c;会有很…

Linux常用命令——gcc命令

在线Linux命令查询工具 gcc 基于C/C的编译器 补充说明 gcc命令使用GNU推出的基于C/C的编译器&#xff0c;是开放源代码领域应用最广泛的编译器&#xff0c;具有功能强大&#xff0c;编译代码支持性能优化等特点。现在很多程序员都应用GCC&#xff0c;怎样才能更好的应用GCC…

【MySQL数据库】MySQL日志管理、备份与恢复

MySQL日志管理、备份与恢复 一、MySQL日志管理1.1日志存放位置 二、数据备份2.1物理备份与逻辑备份2.2完整备份、差异备份、增量备份2.3常见的备份方法 三、完整备份与恢复3.1物理冷备份与恢复3.2mysqldump 备份3.3mysqldump数据恢复3.4MySQL增量备份3.5MySQL增量恢复 一、MySQ…

【开发细节】SpringBoot配置文件的spring.profiles下的active和include属性的区别和作用

目录 问题作用spring.profiles.activespring.profiles.include 总结 问题 我们经常在项目的application.yml中看到这样的配置&#xff0c;如下&#xff1a; 在 Spring Boot 中&#xff0c;spring.profiles.active 和 spring.profiles.include 属性都是用来配置 profile 的。 …

【VB6|第18期】基于libxl导出Excel之导出失败的解决方案

日期&#xff1a;2023年6月12日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xf…

安装Hive

安装Hive 准备 安装Java环境&#xff1a;Hive需要Java环境支持&#xff0c;所以需要先安装Java。安装文档&#xff1a;http://t.csdn.cn/deBJu 安装MySQL数据库。http://t.csdn.cn/d24pN 下载Hive 下载Hive的二进制文件。 链接&#xff1a;https://pan.baidu.com/s/1fdg7…

ubuntu 22.04部署dzzoffice及安装onlyoffice插件

目录 一、配置阿里源 二、安装数据库 三、安装依赖组件 &#xff08;一&#xff09;安装php7.4 &#xff08;二&#xff09;安装apache2 四、下载 dzzoffice 五、安装dzzoffice 六、安装onlyoffice插件 &#xff08;一&#xff09;从github下载小胡版onlyoffice替代原来…

Spring MVC 的创建连接和使用

目录 前言&#xff1a; MVC 是什么&#xff1f; 1. Spring MVC 项目的创建和连接&#xff1a; 1.1 创建 1.2 连接 2. RequestMapping 注解使用详析&#xff1a; 2.1 指定请求类型&#xff1a; 2.1.1 指定 GET 请求 2.1.2 指定 POST 请求 3. 参数的获取与传递&#xff1a; 3.1 传…

若依微服务 + seata1.5.2版本分布式事务(安装配置nacos+部署)

若依官方使用的1.4.0版本seata&#xff0c;版本较低配置相对更麻烦一些 一、seata服务端下载&#xff0c;下载方式介绍两种入口&#xff0c;如下&#xff1a; 1、找到对应版本&#xff0c;下载 binary 即可。 下载包名为&#xff1a;seata-server-1.5.2.zip 2. github上下载 …

Stable Diffusion WebUI 本地安装教学

Stable diffusion AI的绘图工具&#xff0c;这是一种扩散模型&#xff0c;可以通过不断去噪来获得最终的艺术作品。这款工具是当前最受欢迎的AI绘图工具之一&#xff0c;不仅是还是开源的&#xff0c;而且其中的AUTOMATIC111 Stable-diffusion-webui版本深受AI绘图玩家的喜爱&a…

《统计学习方法》——条件随机场#习题解答#

引言 这是统计学习方法第十一章条件随机场的阅读笔记&#xff0c;包含所有公式的详细推导。 条件随机场(conditional random field,CRF)是给定一组输入随机变量条件下另一组输出随机变量的条件概率分布模型&#xff0c;其特点是假设输出随机变量构成马尔可夫随机场。 建议先阅…

低学历又如何?我这样的程序员照样可以逆袭

今天分享的这个主题&#xff0c;很可能会带来争议&#xff0c;因为目前优秀毕业生0年就可以拿到 20K 的待遇&#xff0c;这里暂且抛开硕士&#xff0c;985&#xff0c;211的 Top 前几高学校本科生。 毕竟今天的主题的初衷是地点低的程序员如何才能 2-3 年实现 20K 的目的&…

naive-ui NPopconfirm怎么用vue3的h()渲染

先看效果 然后我先贴代码&#xff0c; 你们看懂的先运行下&#xff0c; 文章后面我教你怎么 添加这种有template&#xff0c;有slot插槽的组件 h(NPopconfirm,{positiveButtonProps: {size: tiny,color: #007293,bordered: true,},negativeButtonProps: {size: tiny,color: #…

k8s 基本架构

k8s 中支持的 node 数 和 pod 数 k8s 也是逐步发展过来的&#xff0c;来看看以前和现在支持的 node 数 和 pod 数对比 node 即 节点 &#xff0c; 早期的 k8s 版本能够支持 100 台节点&#xff0c;现在 k8s 可以支持到 2000 台了 pod 数&#xff0c;早期的版本可以支持 1000 …

CleanMyMacX4.13.4中文免费版mac电脑管家

CleanMyMac X这款软件集成清理、mac保护、速度优化维护、应用程序管理和文件管理5大功能&#xff0c;使用过程安全高效&#xff0c;用户不必担心误操作导致系统的崩溃。作为一款专业的mac电脑系统管家&#xff0c;CleanMymac X一直致力于更加智能、便捷地全方位维护我们的电脑&…

最近跳槽,压力真大...

前几天&#xff0c;跟个老朋友吃饭&#xff0c;他最近想跳槽去大厂&#xff0c;觉得压力很大&#xff0c;问我能不能分享些所谓的经验套路。 每次有这类请求&#xff0c;都觉得有些有趣&#xff0c;不知道你发现没有大家身边真的有很多人不知道怎么面试&#xff0c;也不知道怎…

数据库表的操作

目录 前言 1.创建表 2.查看表 2.1查看表结构 2.2查看表中插入的数据 3.修改表 4.删除表 总结 前言 前面已经介绍了对数据库的操作&#xff0c;今天我们介绍的是数据库表的操作&#xff0c;数据库表简单可以理解为存储数据的介质。有了这个认识之后&#xff0c;下面我们…