JavaEE 多线程第三节 (lambda方法实现多线程/Thread属性和方法/前台线程后台线程)

欢迎阅读前序课程JavaEE 多线程第二节 (多线程的简单实现Thread/Runable)-CSDN博客

1. lambda方法实现多线程


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

        while (true){
            System.out.println("Hello Main");
            Thread.sleep(1000);
        }
    }
}

2. Thread属性和方法

1. 属性----->名称

public class Test {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            while (true){
                System.out.println("helloworld");
                try {
                    Thread.sleep(1000);
                 } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        },"自定义线程");
        t.start();

        while (true){
            System.out.println("Hello Main");
            Thread.sleep(1000);
        }
    }
}

可以从jconsole查看

2.方法

public class Test {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            while (true){
                System.out.println("helloworld");
                try {
                    Thread.sleep(1000);
                 } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        },"自定义线程");
        t.start();

        System.out.println("线程ID"+ t.getId());
        System.out.println("线程名字"+ t.getName());
        System.out.println("线程状态"+ t.getState());
        System.out.println("线程优先级"+t.getPriority());
    }
}

 isAlive

运行结果:

  • t.start() 之前,t.isAlive() 返回 false,因为线程还没有启动。
  • 调用 t.start() 之后,线程开始执行任务,此时 t.isAlive() 返回 true
  • 主线程通过 Thread.sleep(5000) 休眠 5 秒,确保给线程 t 足够的时间去完成任务(线程 t 每次休眠 1 秒,总共循环 3 次,因此需要约 3 秒完成)。
  • t 线程的任务执行完后,t.isAlive() 再次返回 false,因为线程已经结束。

关键点:

  1. 线程状态
    • isAlive() 方法用于检查线程是否还在运行。当线程启动并未终止时,返回 true;否则返回 false
  2. 线程执行过程
    • 你创建了一个线程 t,其任务是在循环中打印 "helloworld" 三次,每次打印后休眠 1 秒。通过 t.start() 启动线程,JVM 会为这个线程分配时间片执行任务。
  3. 线程的生命周期
    • 线程的状态会经历几个阶段:
      1. 新建状态(New):线程 t 刚创建时,还未调用 start()
      2. 就绪状态(Runnable):调用 start() 之后,线程进入就绪状态,等待 JVM 调度执行。
      3. 运行状态(Running):线程被调度并开始执行 run() 方法中的代码。
      4. 终止状态(Terminated):当 run() 方法执行完毕,线程进入终止状态,此时 isAlive() 返回 false

 3. 前台线程后台线程

1. 前台线程 vs 后台线程

  • 前台线程(用户线程):

    • 默认情况下,Java中的线程都是前台线程。
    • JVM不会终止,直到所有前台线程都结束。如果有任何前台线程还在运行,JVM会继续执行。
    • 举例:在你的代码中,如果你不调用 t.setDaemon(true),线程 t 就是一个前台线程,意味着即使 main 方法结束,JVM也不会退出,因为 t 线程在不停地输出 "helloworld"
  • 后台线程(守护线程):

    • 后台线程通常是为其他线程提供服务的线程,比如垃圾回收线程。
    • JVM会在所有前台线程都结束后终止,不管后台线程是否还在运行
    • 通过 Thread.setDaemon(true) 将一个线程设为后台线程。
    • 如果你设置了 t.setDaemon(true),意味着 t 是一个后台线程,当 main 线程(前台线程)结束后,JVM会终止,后台线程 t 也会随之停止,不再继续运行。

2. 结合代码讲解

public class Test {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            while (true){
                System.out.println("helloworld");
                try {
                    Thread.sleep(1000);
                 } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        },"自定义线程");
        t.setDaemon(true);
        t.start();
        //t变为守护线程不能组织线程结束

    }
}

运行一次就结束了 

3. 执行流程

  • Thread t 是一个线程对象,线程的任务是通过 lambda 表达式定义的,循环输出 "helloworld" 并每秒钟休眠一次。
  • t.setDaemon(true) 这行代码将 t 线程设为守护线程。这意味着,当所有前台线程结束时,守护线程 t 也会结束,而不管它是否仍然在运行。
  • t.start() 启动线程 t,线程进入运行状态,开始打印 "helloworld"
  • 重点:由于 t 是后台线程,当 main 方法执行结束,JVM 会停止所有后台线程并终止运行。因此,t 的运行时间会非常短暂。

4. 前台和后台线程的区别总结

  • 前台线程(用户线程):
    • 会阻止 JVM 退出。
    • 即使所有后台线程结束,前台线程还在运行,JVM 也不会停止。
  • 后台线程(守护线程):
    • 当所有前台线程结束时,JVM 会终止,即使后台线程还在运行。
    • 守护线程通常用于执行一些后台服务,比如垃圾回收。

5. 关于这段代码的实际行为

如果你将 t.setDaemon(true) 改为 t.setDaemon(false)(或者直接不调用它,默认是前台线程),t 就变为前台线程。此时,即使 main 线程结束,JVM 也会继续运行,因为 t 线程还在运行,它会一直每秒钟输出 "helloworld"

然而,使用了 t.setDaemon(true) 后,t 成为后台线程。当 main 线程结束时,t 线程会立即终止,不再输出 "helloworld"

总结:

  • 守护线程通常用于执行后台任务或辅助功能(如垃圾回收器),它不应该是程序的核心逻辑。
  • 用户线程(前台线程)是程序的核心工作线程,确保程序在完成任务后才退出。

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

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

相关文章

探索云边缘与边缘云:技术革新与应用前景

#1024程序员节|征文# 在当今数字化快速发展的时代,云计算已经成为了企业和个人处理和存储数据的重要手段。然而,随着物联网(IoT)设备的爆炸式增长以及对低延迟、高带宽和实时处理的需求不断增加,云边缘和边…

简单介绍市面上的四款录屏软件!!!!

数字化时代,无论是工作还是生活中,录屏已经成为一个不可或缺的工具。然而,选择一款适合自己需求的录屏软件却并不容易。今日来为大家推荐四款超好用的录屏软件,分析这些软件的优缺点,让你在各种场景下都能轻松捕捉精彩…

vue3 解决背景图与窗口留有间隙的问题

需要实现一个登录界面&#xff0c;login.vue的代码如下&#xff1a; <script> import { ref } from vue;export default {setup() {return {};}, }; </script><template><div id"login-container" class"login-container"><di…

Tcp协议讲解与守护进程

TCP协议&#xff1a;面向链接&#xff0c;面向字节流&#xff0c;可靠通信 创建tcp_server 1.创建套接字 域&#xff1a;依旧选择AF_INET 连接方式&#xff1a; 选择SOCK_STREAM 可靠的 2.bind 3.监听装置 client要通信&#xff0c;要先建立连接&#xff0…

Allegro怎么批量将弧形线改成45度角的线?

Allegro如何将弧形线改成45度角的线? 在用Allegro进行PCB设计时,有时候需要将弧形线改为45度角的线。 具体操作方法如下: 1、选择菜单栏Route 选择Unsupported Prototypes(不支持的原型)→AICC 2、在Options选项卡选择45度 3、在Find选项卡选择Nets,选择网络可以批量转换…

浮动练习(3)

##每台电脑分辨率不同&#xff0c;数值高度宽度需要自己调&#xff0c;仅供参考 <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title></title> <style> div{ …

JMeter详细介绍和相关概念

JMeter是一款开源的、强大的、用于进行性能测试和功能测试的Java应用程序。 本篇承接上一篇 JMeter快速入门示例 &#xff0c; 对该篇中出现的相关概念进行详细介绍。 JMeter测试计划 测试计划名称和注释&#xff1a;整个测试脚本保存的名称&#xff0c;以及对该测试计划的注…

《使用Gin框架构建分布式应用》阅读笔记:p108-p126

《用Gin框架构建分布式应用》学习第8天&#xff0c;p108-p126总结&#xff0c;总计18页。 一、技术总结 1.Redis eviction policy (1)什么是 eviction policy? The eviction policy determines what happens when a database reaches its memory limit. (2)配置示例 在r…

Dockerfile样例

一、基础jar镜像制作 ## Dockerfile FROM registry.openanolis.cn/openanolis/anolisos:8.9 RUN mkdir /work ADD jdk17.tar.gz fonts.tar.gz /work/ RUN yum install fontconfig ttmkfdir -y && yum clean all && \chmod -R 755 /work/fonts ADD fonts.conf …

docker配置mysql8报错 ERROR 2002 (HY000)

通过docker启动的mysql&#xff0c;发现navicat无法连接&#xff0c;后来进入容器内部也是无法连接&#xff0c;产生以下错误 root9f3b90339a14:/var/run/mysqld# mysql -u root -p Enter password: ERROR 2002 (HY000): Cant connect to local MySQL server through socket …

二叉树中的最长交错路径

题目链接 二叉树中的最长交错路径 题目描述 注意点 每棵树最多有 50000 个节点每个节点的值在 [1, 100] 之间起点无需是根节点 解答思路 要找到最长交错路径&#xff0c;首先想到的是深度优先遍历因为起点无需是根节点&#xff0c;所以对于任意一个节点&#xff0c;其可以…

4个在线音频剪辑工具,让你的声音更加动听。

最近我开始接触音乐剪辑&#xff0c;想把一些歌曲进行剪辑创作&#xff1b;于是在网上好多了很多的音频剪辑软件进行试用&#xff0c;一番下来&#xff0c;发现了4款使用起来体验感比较好的专业剪辑工具&#xff0c;在这里跟大家分享分享。这些工具都可以被应用于歌曲创作&…

Linux系统基础-进程间通信(3)_模拟实现匿名管道

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 Linux系统基础-进程间通信(3)_模拟实现匿名和命名管道 收录于专栏[Linux学习] 本专栏旨在分享学习Linux的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&a…

【优先算法】--双指针1

“一念既出&#xff0c;万山无阻。”加油陌生人&#xff01; 目录 1.双指针--移动零 2.双指针-复写零 ok&#xff0c;首先在学习之前&#xff0c;为了方便大家后面的学习&#xff0c;我们这里需要补充一个知识点&#xff0c;我这里所谓的指针&#xff0c;不是之前学习的带有…

dolphinscheduler创建工作流及工作流中DataX的使用(简单操作)

一、在项目管理中创建项目&#xff1a;点击创建项目 用哪个用户登录的&#xff0c;所属用户就是哪个&#xff0c;直接输入项目名即可 二、点击项目&#xff0c;在项目中创建工作流&#xff0c;用DataX同步数据 按照图片的步骤依次填写完成&#xff0c;注意 图片中的第九步是写…

2024年双十一腾讯阿里云香港服务器优惠活动汇总

2024年双11狂欢节终于来了&#xff0c;按照往年的惯例&#xff0c;各大云服务器厂商通常会在10月20号左右开始上线新的活动&#xff0c;今年双11期间国内各大云服务器厂商都有哪些活动呢&#xff1f;有哪些活动包括香港云服务器呢&#xff1f;是否有海外服务器的优惠折扣呢&…

HelpLook联合MarketUP发布《2024企业内容营销实战》白皮书!(内附下载链接)

B2B内容营销为什么值得反复讲&#xff1f; 这是一个技术创新、客户聚焦、回归内容的B2B时代&#xff0c;B2B市场源源不断地诞生新故事&#xff0c;从短视频到AIGC&#xff0c;从新产品到新技术&#xff0c;内容始终是所有B2B活动的核心&#xff0c;需要更新更深的内容营销塑造…

Xmind一款极简思维导图和头脑风暴软件,支持PC和移动端,Xmind 2024.10.01101版本如何升级到Pro版?简单操作,最新可用!

文章目录 Xmind下载安装Xmind免费升级到Pro Xmind 是一款全功能的思维导图和头脑风暴软件&#xff0c;不限制节点和文件数&#xff0c;创新无限&#xff0c;界面纯净简洁无广告&#xff0c;支持PC和移动端&#xff0c;思维导图和大纲视图自由切换&#xff0c;可本地化文档存储&…

新版idea菜单栏展开与合并

新版idea把菜单栏合并了看着很是不习惯&#xff0c;找了半天原来在这里展开 ① 点击文件 -> 设置 ② 点击外观与行为 -> 外观 -> 合并主菜单和窗口标题 然后确定&#xff0c;重启即可

【LeetCode每日一题】——523.连续的子数组和

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 前缀和 二【题目难度】 中等 三【题目编号】 523.连续的子数组和 四【题目描述】 给你一个…