线程的创建和使用(二)

news2024/11/29 3:56:04

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: 工作完成了.

 

 

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

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

相关文章

【SpringCloud-5】gateway网关

网关是干啥用的就不用再说了。 sringcloud中的网关&#xff0c;第一代是zuul&#xff0c;但是性能比较差&#xff08;1.x是阻塞式的&#xff0c;2.x是基于Netty的&#xff09;&#xff0c;然后有了第二代GateWay&#xff0c;基于Reactor模型 异步非阻塞。 springcloud网关就是一…

经理的工作岗位职责描述10篇

经理的工作岗位职责描述&#xff08;篇1&#xff09; 1、销售工具的开发和制作 2、负责各类媒体、渠道的软文撰写&#xff0c;产品信息推广; 3、筹办重点客户&#xff0c;潜在客户的讲座论坛会议; 4、市场推广活动&#xff1a;展会seminar oadshow等活动 5、产品上市沟通&#…

IIC协议通信解析,内附完整代码。

一&#xff1a;硬件接口 1.1&#xff1a;功能引脚 1.2&#xff1a;IIC总线通信注意事项 二&#xff1a;通信协议 &#xff08;1&#xff09;空闲状态&#xff1a; &#xff08;2&#xff09;起始位&#xff1a; &#xff08;3&#xff09;有效数据位 &#xff08;4&#x…

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

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

【玩转Docker小鲸鱼叭】MacOS系统配置Docker镜像加速器

当我们通过 docker pull拉取镜像时&#xff0c;如果不指定仓库&#xff0c;默认从 Docker Hub &#xff08;docker.io&#xff09;获取镜像&#xff0c;而国内用户访问Docker Hub仓库时&#xff0c;通常速度很忙&#xff0c;经常超时导致拉取镜像失败&#xff0c;所以通常要通过…

上海亚商投顾:沪指震荡调整 CPO概念股持续大涨

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 市场情绪 沪指今日震荡调整&#xff0c;保险等权重板块走低&#xff0c;上证50跌超1.5%&#xff0c;创业板指较为抗跌。CPO、…

【新固态格式化】

新固态格式化 初始化硬盘 从管理进入磁盘管理 Windows 7及其以后的系统建议使用GPT MBR 是 Master Boot Record 的缩写&#xff0c;是一种传统而常用的磁盘布局。GPT 是 Globally Unique Identifier Partition Table 的缩写&#xff0c;是一种与 UEFI 相关的新磁盘布局。其…

Day23 实战篇 ——Jmeter压力测试实战

Day23 实战篇 ——Jmeter压力测试实战 文章目录 Day23 实战篇 ——Jmeter压力测试实战一、分布式压测原理二、分布式环境配置Slaves机器配置Master机器配置参数化文件配置三、分布式压测执行Slave机器执行Master机器执行四、常见问题处理问题一问题二问题三问题四项目中使用Jme…

redis缓存设计-Redis(八)

上篇文章介绍了redis缓存设计&#xff0c;热点key&#xff0c;bigkey注意事项。 原创 redis缓存设计-Redis&#xff08;七&#xff09;https://blog.csdn.net/ke1ying/article/details/131268967 命令使用 hgetall&#xff0c;lrange&#xff0c;smembers&#xff0c;zrange…

【初识Linux】——01Linux系统

目录索引 Linux介绍&#xff1a;Linux历史&#xff1a;Linux系统应用&#xff1a;*服务器系统&#xff1a;**嵌入式系统&#xff1a;**桌面应用系统&#xff1a;**版本&#xff1a;* Linux系统的安装&#xff1a;虚拟机&#xff1a;安装VMware&#xff1a;安装centOS操作系统&a…

【AI实战】开源可商用的中英文大语言模型baichuan-7B,从零开始搭建

【AI实战】开源可商用的中英文大语言模型baichuan-7B&#xff0c;从零开始搭建 baichuan-7B 简介baichuan-7B 中文评测baichuan-7B 搭建参考 baichuan-7B 简介 baichuan-7B 是由百川智能开发的一个开源可商用的大规模预训练语言模型。基于 Transformer 结构&#xff0c;在大约…

解决安卓12限制32个线程

Android 12及以上用户在使用Termux时&#xff0c;有时会显示[Process completed (signal 9) - press Enter]&#xff0c;这是因为Android 12的PhantomProcesskiller限制了应用的子进程&#xff0c;最大允许应用有32个子进程。 这里以ColorOS 12.1为例&#xff08;其他系统操作略…

状态机编程实例-嵌套switch-case法

嵌入式软件开发中&#xff0c;状态机编程是一个比较实用的代码实现方式&#xff0c;特别适用于事件驱动的系统。 本篇&#xff0c;以一个炸弹拆除的小游戏为例&#xff0c;介绍状态机编程的思路。 C/C语言实现状态机编程的方式有很多&#xff0c;本篇先来介绍最简单最容易理解…

uni-app uni-file-picker文件上传实现拍摄从相册选择获取图片上传文档服务器

前言 最近在使用uni-app写H5移动端&#xff0c;有一个从手机拍摄从相册选择获取图片上传到文档服务器功能。 查阅uni-app发现关于上传图片&#xff0c;uni-file-picker文件上传&#xff0c;uni.chooseImage&#xff0c;uni.uni.uploadFile 它和pc端原理差不多&#xff0c;都是…

5年测试经验,测试老鸟总结功能测试——全测试点覆盖

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 功能测试主要包括…

使用vscode编写并运行typescript代码

1.安装vsCode Visual Studio Code - Code Editing. Redefined 2.安装nodejs 下载 | Node.js 中文网 3.打开vscode&#xff0c;在vscode里面打开终端&#xff08;快捷键是ctrl~) 查看是否成功安装node和npm&#xff1a; node -v npm -v 在终端中输入如下命令并…

ELK详细安装配置

1.安装jdk1.8&#xff08;略&#xff09; 2.安装配置本机防火墙&#xff08;略&#xff09; 3.ELK版本选择 参考&#xff1a;支持一览表 | Elastic 选择支持java8的版本 4.版本6安装 root依次用户执行 wget https://artifacts.elastic.co/downloads/elasticsearch/elast…

C++基础(1)——程序内存模型和引用

前言 本文主要介绍了C中内存模型的四区及存放的数据&#xff0c;引用的基本语法。 1.1&#xff1a;代码区&#xff08;程序运行前&#xff09; 1&#xff1a;存放CPU执行的机器指令 2&#xff1a;代码区是共享的&#xff0c;共享的目的是对于频繁被执行的程序&#xff0c;只…

在Centos Stream 9上Docker的实操教程(七) - Docker上实现MYSQL实现主从复制

&#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Micro麦可乐的博客 &#x1f425;《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程&#xff0c;入门到实战 &#x1f33a;《RabbitMQ》…

第3章 作业(268EF)【网络安全】

第3章 作业【网络安全】 前言推荐第3章 作业268EF如何不用计算机计算求模 最后 前言 2023-6-19 15:49:17 以下内容源自《网络安全》 仅供学习交流使用 推荐 第2章 作业&#xff08;2456&#xff09;【网络安全】 第3章 作业 2 3.2什么是MAC? MAC&#xff1a;消息认证码…