当前位置: 首页 > news >正文

Java线程学习笔记

    1、判断线程存活

   

        1. 当线程run()或者call()方法执行结束,线程进入终止状态

        2. 当线程内发生异常,并且异常没有被捕获,线程进入终止状态

        3. 线程调用stop()方法后,线程进入终止状态(不推荐使用)

       

        当主线程结束时,其他线程不受任何影响,并不会随之结束。一旦子线程启动起来后,它就拥有和主线程相同的地位,它不会受主线程的影响。

        为了测试某个线程是否已经死亡,可以调用线程对象的isAlive()方法,当线程处于就绪、运行、阻塞3种状态时,该方法将返回true;当线程处于新建、死亡2种状态时,该方法将返回false。

/**

 * isAlive()方法练习

   */

   public class IsAliveDemo1 {

   public static void main(String[] args) throws InterruptedException {

       Thread t = new Thread(()->{

           for (int i = 0; i < 50; i++) {

               System.out.println(i);

           }

       });

       System.out.println("线程的状态:"+t.getState());//NEW

       System.out.println("线程启动前:"+t.isAlive());//false

       System.out.println("----------------------");

       t.start();

       System.out.println("线程的状态:"+t.getState());//RUNNABLE

       System.out.println("线程启动后:"+t.isAlive());//true

       System.out.println("----------------------");

       TimeUnit.SECONDS.sleep(5);

       System.out.println("线程的状态:"+t.getState());//TERMINATED

       System.out.println("线程结束后:"+t.isAlive());//false

   }

   }

/**

 *isAlive()方法练习2

 */

public class IsAliveDemo2 {

    public static void main(String[] args) throws InterruptedException {

        Thread t = new Thread(()->{

            for (int i = 0; i < 40; i++) {

                System.out.println(i);

                if(i==15){

                    synchronized (IsAliveDemo2.class){

                        try {

                            IsAliveDemo2.class.wait();

                        } catch (InterruptedException e) {

                            throw new RuntimeException(e);

                        }

                    }

                }

            }

        });

        //启动前获取状态

        System.out.println("线程启动前:"+t.isAlive());

        t.start();

        System.out.println("线程启动后:"+t.isAlive());

        //主线程休眠2秒,给予t线程充足的执行时间

        TimeUnit.SECONDS.sleep(2);

        System.out.println("线程抛出异常后:"+t.isAlive());

    }

}

       

        注意:不要对处于死亡状态的线程调用start()方法,程序只能对新建状态的线程调用start()方法,对新建状态的线程两次调用start()方法也是错误的。这都会引发IllegalThreadState Exception异常。

/**

 * 练习3

   */

   public class IsAliveDemo3 {

   public static void main(String[] args) throws InterruptedException {

       Thread t = new Thread(()->{

           for (int i = 0; i < 10; i++) {

               System.out.println(i);

           }

       });

       t.start();

       //t.start(); 抛出IllegalThreadStateException异常

       TimeUnit.SECONDS.sleep(2);

       System.out.println(t.getState());//TERMINATED

       //t.start(); 抛出IllegalThreadStateException异常

   }

   }

   2、线程控制

   (1)Join()

    join()方法相当于插入,例如在T2线程中调用了线程T1.join()方法,则T2线程会一直等待T1线程执行结束后再继续执行。

    就是在A线程中调用线程B的join()方法,线程A会一直等待直到线程B执行结束再执行,也可以理解为插队。

   

    注意:当T2线程执行过程中被T1线程Join,线程T1执行时,T2处于WAITING

/**

 * Join()方法

   */

   public class JoinDemo1 {

   public static void main(String[] args) throws InterruptedException {

       Thread t1 = new Thread(()->{

           for (int i = 0; i < 30; i++) {

               System.out.println(Thread.currentThread().getName()+"--------->"+i);

           }

       },"t1");

       Thread t2 = new Thread(()->{

           for (int i = 0; i < 30; i++) {

               System.out.println(Thread.currentThread().getName()+"#########"+i);

               if (i == 10){

                   try {

                       //t1线程调用t2线程的join()方法,插队执行

                       t1.join();

                   } catch (InterruptedException e) {

                       throw new RuntimeException(e);

                   }

               }

           }

       },"t2");

       t1.start();

       System.out.println(t1.getState());

       t2.start();

       //main t1 t2 三个线程交替执行

       for (int i = 0; i < 60; i++) {

           System.out.println(Thread.currentThread().getName()+"***********"+i);

       }

   }

   }


 

   (2)Join(long millis)

    如果T2线程执行过程中调用为了T1线程的join(long millis)方法,T2线程最多等待T1线程millis毫秒,到达时间后,如果T1线程没有结束,则和T2线程交替执行。

   

    注意:T2线程被T1线程join(millis)后,T2线程在等待T1线程执行的过程中处于TIMED_WAITING状态    

/**

 * Join()方法

   */

   public class JoinDemo2 {

   public static void main(String[] args) throws InterruptedException {

       Thread t1 = new Thread(()->{

           for (int i = 0; i < 50; i++) {

               System.out.println(Thread.currentThread().getName()+"-------->"+i);

               try {

                   TimeUnit.SECONDS.sleep(1);

               } catch (InterruptedException e) {

                   throw new RuntimeException(e);

               }

           }

       },"t1");

       Thread t2 = new Thread(()->{

           for (int i = 0; i < 200; i++) {

               System.out.println(Thread.currentThread().getName()+"##########"+i);

               if (i == 20){

                   //启动t1线程

                   t1.start();

                   try {

                       //在线程t2中插入

                       t1.join(3000);

                   } catch (InterruptedException e) {

                       throw new RuntimeException(e);

                   }

               }

           }

       },"t2");

       //启动进程

       t2.start();

       System.out.println("--------------------");

       //主线程休眠 让t2线程执行

       TimeUnit.SECONDS.sleep(2);

       //t2线程的状态

       System.out.println(t2.getState());//TIMED_WAITING

   }

   }

   (3)守护线程

    在后台运行的,并为其他的线程提供服务的线程被称为“后台线程”,又称为“守护线程”,JVM的垃圾回收线程就是典型的后台线程。

    特征:如果所有的前台线程都死亡,后台线程会自动死亡。

   

    守护线程必须在启动前将其守护状态设置为true,启动之后不能再将用户线程设置为守护线程,否则JVM会抛出一个InterruptedException异常。具体来说,如果线程为守护线程,就必须在线程实例的start()方法调用之前调用线程实例的setDaemon(true),设置其daemon实例属性值为true。

    守护线程存在被JVM强行终止的风险,所以在守护线程中尽量不去访问系统资源,如数据库连接。守护线程被强行终止时,可能会引发系统资源操作不负责任的中断,从而导致资源不可逆的损坏。

    守护线程创建的线程也是守护线程。在守护线程中创建的线程,新的线程都是守护线程。在创建之后,如果通过调用setDaemon(false)将新的线程显式地设置为用户线程,新的线程可以调整成用户线程。

/**

 * setDaemon()方法

   */

   public class DaemonDemo {

   public static void main(String[] args) {

       Thread t1 = new Thread(()->{

           for (int i = 0; i < 100; i++) {

               System.out.println(Thread.currentThread().getName()+"===="+i);

           }

       },"t1");

       //设置线程为守护线程 必须在启动前设置

       t1.setDaemon(true);

       t1.start();

       //主线程循环次数大幅少于守护线程,当前台线程执行结束时 守护线程不管是否执行完毕都会结束

       for (int i = 0; i < 10; i++) {

           System.out.println(Thread.currentThread().getName()+">>>>"+i);

       }

   }

   }


 

相关文章:

Java线程学习笔记

1、判断线程存活 1. 当线程run()或者call()方法执行结束&#xff0c;线程进入终止状态 2. 当线程内发生异常&#xff0c;并且异常没有被捕获&#xff0c;线程进入终止状态 3. 线程调用stop()方法后&#xff0c;线程进入终止状态(不推荐使用) 当主线程结束时&#xff0c;其他线程…...

平面光波导_三层均匀平面光波导_射线分析法

平面光波导_三层均匀平面光波导_射线分析法 三层均匀平面光波导&#xff1a; 折射率沿 x x x 方向有变化&#xff0c;沿 y y y、 z z z 方向没有变化三层&#xff1a;芯区( n 1 n_1 n1​) > > > 衬底( n 2 n_2 n2​) ≥ \geq ≥ 包层( n 3 n_3 n3​)包层通常为空…...

IPV6学习记录

IPV6的意义 从广义上来看IPV6协议包含的内容很多: IPV6地址的生成与分配 IPV6的报头的功能内容 IPV4网络兼容IPV6的方案 ICMPv6的功能(融合了arp和IGMP功能) IPV6的路由方式 ipv6的诞生除了由于ipv4的地址枯竭外&#xff0c;很大程度上也是因为ipv4多年的发展产生了很多…...

使用proteus进行主从JK触发器仿真失败原因的分析

在进行JK触发器的原理分析的时候&#xff0c;我首先在proteus根据主从JK触发器的原理进行了实验根据原理图&#xff0c;如下图&#xff1a; 我进行仿真&#xff0c;在仿真的过程中&#xff0c;我向电路图中添加了外部的置0/1端口&#xff0c;由此在proteus中得到下面的电路图 …...

Golang基础入门及Gin入门教程(2024完整版)

Golang是Google公司2009年11月正式对外公开的一门编程语言&#xff0c;它不仅拥有静态编译语言的安全和高性能&#xff0c;而 且又达到了动态语言开发速度和易维护性。有人形容Go语言&#xff1a;Go C Python , 说明Go语言既有C语言程序的运行速度&#xff0c;又能达到Python…...

202312 青少年软件编程(C/C++)等级考试试卷(四级)电子学会真题

2023年12月 青少年软件编程&#xff08;C/C&#xff09;等级考试试卷&#xff08;四级&#xff09;电子学会真题 1.移动路线 题目描述 桌子上有一个m行n列的方格矩阵&#xff0c;将每个方格用坐标表示&#xff0c;行坐标从下到上依次递增&#xff0c;列坐标从左至右依次递增…...

leetcode-合并两个有序数组

88. 合并两个有序数组 题解&#xff1a; 这是一个经典的双指针问题&#xff0c;我们可以使用两个指针分别指向nums1和nums2的最后一个元素&#xff0c;然后比较两个指针所指向的元素大小&#xff0c;将较大的元素放入nums1的末尾&#xff0c;并将对应的指针向前移动一位。重复…...

网站怎么做google搜索引擎优化?

网站想做google搜索引擎优化&#xff0c;作为大前提&#xff0c;您必须确保网站本身符合google规范&#xff0c;我们不少客户实际上就连这点都无法做到 有不少客户公司自己本身有技术&#xff0c;就自己弄一个网站出来&#xff0c;做网站本身不是难事&#xff0c;但前提是您需要…...

TDengine 签约西电电力

近年来&#xff0c;随着云计算和物联网技术的迅猛发展&#xff0c;传统电力行业正朝着数字化、信息化和智能化的大趋势迈进。在传统业务基础上&#xff0c;电力行业构建了信息网络、通信网络和能源网络&#xff0c;致力于实现发电、输电、变电、配电和用电的实时智能联动。在这…...

赛门铁克OV代码签名证书一年多少钱?

在当前&#xff0c;软件和应用程序的安全性变得尤为重要。为了保护软件的完整性和安全性&#xff0c;越来越多的开发者和厂商开始采用代码签名的方式来确保软件的真实性和完整性。赛门铁克OV代码签名证书成为了其中一个备受信任的选择。那么&#xff0c;赛门铁克OV代码签名证书…...

Dockerfile详解

文章目录 一、Dockerfile介绍二、常用指令三、Dockerfile示例四、最佳实践 一、Dockerfile介绍 Dockerfile是一个包含创建镜像所有命令的文本文件&#xff0c;通过docker build命令可以根据Dockerfile的内容构建镜像。 一般的&#xff0c;Dockerfile分为四部分&#xff1a;基础…...

零基础小白如何自学sql?

学习SQL对于数据分析和处理来说非常重要。SQL是一种强大的工具&#xff0c;可以帮助你与数据库沟通&#xff0c;提取&#xff0c;整理和理解数据。 以下是一些学习SQL的建议&#xff1a; 01 前期&#xff1a;SQL数据库学习 了解SQL的基本概念&#xff1a;首先&#xff0c;你…...

【刷题笔记2】

刷题笔记2 最小公倍数、最大公约数 两个数的最大公约数两数乘积/最小公倍数 #<include> cmath; int a,b; int mgcd(a,b);//求最大公约数复制字符串substr()函数 s.substr(pos, len) &#xff1a;pos的默认值是0&#xff0c;len的默认值是s.size() - pos string a1;in…...

Kafka之集群搭建

1. 为什么要使用kafka集群 单机服务下&#xff0c;Kafka已经具备了非常高的性能。TPS能够达到百万级别。但是&#xff0c;在实际工作中使用时&#xff0c;单机搭建的Kafka会有很大的局限性。 ​ 消息太多&#xff0c;需要分开保存。Kafka是面向海量消息设计的&#xff0c;一个T…...

Linux备忘手册

常⽤命令 作⽤ shutdown -h now 即刻关机 shutdown -h 10 10分钟后关机 shutdown -h 11:00 11&#xff1a;00关机 shutdown -h 10 预定时间关机&#xff08;10分钟后&#xff09; shutdown -c 取消指定时间关机 shutdown -r now 重启 shutdown -r 10 10分钟之后重启 shutdown -…...

Qt中QGraphicsView总体架构学习

前沿 前段时间学习了下如何在QGraphicsView架构中绘制刻度尺&#xff0c;主要是与OnPainter中进行比较的&#xff0c;那么今天就来详细讲解下我对QGraphicsView框架的认知吧~ 最近一段时间想学习下&#xff0c;如果我有不正确的&#xff0c;欢迎留言探讨哟~ QGraphicsView架…...

STL-list的使用简介

目录 ​编辑 一、list的底层实现是带头双向循环链表 二、list的使用 1、4种构造函数&#xff08;与vector类似&#xff09;​编辑 2、迭代器iterator 3、容量&#xff08;capicity&#xff09;操作 4、element access 元素获取 5、增删查改 list modifiers 6、list的迭…...

MySQL:索引失效场景总结

1 执行计划查索引 通过执行计划命令可以查看查询语句使用了什么索引。 EXPLAIN SELECT * FROM ods_finebi_area WHERE areaName = 福建 执行查询计划后,key列的值就是被使用的索引的名称,若key列没有值表示查询未使用索引。 2 在什么列上创建索引 (1)列经常被用于where…...

LNMP平台对接redis服务

目录 1、安装 LNMP 各个组件 2、安装 redis 服务 3、安装 redis 扩展 4、修改 php 配置文件 5、测试连接 1、安装 LNMP 各个组件 2、安装 redis 服务 3、安装 redis 扩展 官网&#xff1a;http://redis.io/ 下载包&#xff1a; https://codeload.github.com/phpredis/p…...

5G之味,在烟火长沙

今年夏天&#xff0c;有一部电影叫做《长沙夜生活》。影片讲述了长沙大排档中的一些故事。网红大排档的老板娘、厨师、顾客&#xff0c;他们的邂逅、热爱、留下、离开、和解、团圆&#xff0c;都发生在一段夜色里&#xff0c;发生在充满烟火气的长沙城。 有没有想过这样一个问题…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

Ubuntu系统复制(U盘-电脑硬盘)

所需环境 电脑自带硬盘&#xff1a;1块 (1T) U盘1&#xff1a;Ubuntu系统引导盘&#xff08;用于“U盘2”复制到“电脑自带硬盘”&#xff09; U盘2&#xff1a;Ubuntu系统盘&#xff08;1T&#xff0c;用于被复制&#xff09; &#xff01;&#xff01;&#xff01;建议“电脑…...

如何在Windows本机安装Python并确保与Python.NET兼容

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

Java数组Arrays操作全攻略

Arrays类的概述 Java中的Arrays类位于java.util包中&#xff0c;提供了一系列静态方法用于操作数组&#xff08;如排序、搜索、填充、比较等&#xff09;。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序&#xff08;sort&#xff09; 对数组进行升序…...