[Java EE初阶]Thread 类的基本用法

news2024/11/24 6:33:01

本就无大事,庸人觅闲愁.

文章目录

  • 1. 线程创建
  • 2. 线程中断
    • 2.1 通知终止后立即终止
    • 2.2 通知终止,通知之后线程继续执行
    • 2.3 通知终止后,添加操作后终止
  • 3. 线程等待
  • 4. 线程休眠
  • 5. 获取线程实例



1. 线程创建

创建线程有五个方法
详情见我的另一个文章
https://editor.csdn.net/md/?articleId=128293107
分别是继承Thread,实现Runnable接口,使用匿名内部类继承Thread,使用匿名内部类,实现Runnale接口,使用Lambda表达式.

2. 线程中断

线程中断是t通过标志位通知线程快要终止了,线程接收到信号后,可以加入自己的操作,做出不同反应.

2.1 通知终止后立即终止

如下代码

public class InterruptedThread {
    public static void main(String[] args)throws InterruptedException {
        Thread t = new Thread(()->{
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("hello thread");
                break;
            }
        });
        t.start();
        t.sleep(1000);
        t.interrupt();
    }
}

说明:
1.Thread.currentThread()的作用是获取当前的进程
2.isInterrupted()源码如下
在这里插入图片描述
线程调用这个函数,获取标志位,也就是true或者false
返回值是false时,通知这个线程未被终止,while()循环继续.
返回值是true时,通知线程即将被终止.是否选择终止,取决于线程之后的操作.
3.t.interrupt(),将标志位改为true,在上述代码中,线程标志位为true时,while循环结束,无其他操作,线程立刻终止.

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

2.2 通知终止,通知之后线程继续执行

	public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
        t.sleep(1000);
        t.interrupt();
    }
   

结果如下图
在这里插入图片描述

说明:
调用t.interrupt();将标志位改为true,如果线程正在sleep,interrupt()会触发sleep内部的异常,导致sleep提前返回,将标志位重新改为false,唤醒进程.
所以,在提醒终止后,线程未选择终止,而是继续执行

2.3 通知终止后,添加操作后终止

	 public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    try {
                        System.out.println("我是添加的操作");
                        System.out.println("1 + 1 = 2");
                        Thread.sleep(500);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                    break;
                }
            }
        });
        t.start();
        t.sleep(1000);
        t.interrupt();
    }

结果如下图
在这里插入图片描述
说明:
t.interrupt(),将标志位改为true,但线程正在sleep,触发catch异常,之后try-catch捕获异常,可以在try中添加操作,之后break,直接跳出循环.

3. 线程等待

线程抢占式执行,随机调度,线程执行的顺序由操作系统操控,不可预知.
线程等待,目的是控制两个线程结束的顺序.
若是在t2中调用t1.join(),意味着t2会等待t1结束后才会终止自身进程.

	public static void main(String[] args) {
        System.out.println("main开始喽");
        Thread t = new Thread(()->{
            for(int i = 0; i < 3; i++){
                System.out.println("hello thread");
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t.start();
        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("main结束喽");
    }

在这里插入图片描述
t.join();执行此代码时,main()函数会等待t线程结束后,再结束自身调度.

4. 线程休眠

操作系统每次只会在就绪序列中选择合适线程执行.
调用sleep()函数,使线程从就绪序列置到阻塞序列
由于线程调度有时间开销,线程休眠结束后,线程唤醒之后不会立即被执行.

5. 获取线程实例

1.使用线程调度两个线程

	public static void concurrency() {
        // 使用两个线程分别完成自增.
        Thread t1 = new Thread(() -> {
            long a = 0;
            for(long i = 0; i < 100_0000_0000L; i++) {
                a++;
            }
        });
        Thread t2 = new Thread(() -> {
            long b = 0;
            for(long i = 0; i < 100_0000_0000L; i++) {
                b++;
            }
        });
        // 开始计时
        long beg = System.currentTimeMillis();
        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 结束计时
        long end = System.currentTimeMillis();
        System.out.println("并发执行时间: " + (end - beg) + " ms");
    }

2.正常调度两个线程

public static void serial() {
        // 为了衡量带没带的执行速度, 加上个计时的操作
        // currentTimeMillis 获取到当前系统的 ms 级时间戳.
        long beg = System.currentTimeMillis();

        long a = 0;
        for (long i = 0; i < 100_0000_0000L; i++) {
            a++;
        }
        long b = 0;
        for (long i = 0; i < 100_0000_0000L; i++) {
            b++;
        }

        long end = System.currentTimeMillis();
        System.out.println("执行时间: " + (end - beg) + " ms");
    }

时间对比,会发现使用线程之后,大大减小时间开销.
在这里插入图片描述


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

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

相关文章

【K8S系列】第十二讲:Service进阶

目录 ​编辑 序言 1.Service介绍 1.1 什么是Service 1.2 Service 类型 1.2.1 NodePort 1.2.2 LoadBalancer 1.2.3 ExternalName 1.2.4 ClusterIP 2.yaml名词解释 3.投票 序言 当发现自己的才华撑不起野心时&#xff0c;就安静下来学习吧 三言两语&#xff0c;不如细…

Unity 灯光

初始化时&#xff0c;系统默认会给一个灯光&#xff0c;类型为定向光。 定向光意为&#xff0c;从无穷远处照射过来的平行光&#xff0c;因此每个图形的阴影的方向一致 灯光的系统参数 阴影类型&#xff1a;①无阴影 ②硬阴影 ③软阴影 &#xff08;注意&#xff09;阴影类型最…

力扣(LeetCode)164. 最大间距(C++)

桶排序(划分区间) 一次遍历找到区间内最大值 MaxMaxMax &#xff0c;最小值 MinMinMin 。区间 (Min,Max](Min,Max](Min,Max] 左开右闭&#xff0c;划分为 n−1n-1n−1 个长度为 lenlenlen 的区间 &#xff0c;划分的区间左开右闭&#xff0c;所以每个子区间有 len−1len-1len−…

SpringCloud学习笔记

SpringCloud学习笔记成熟分布式微服务架构包含技术模块SpringCloud与SpringBoot版本选择SpringCloud各技术模块的技术选择SpringCloud实现订单-支付微服务创建父工程(管理子工程即各个微服务)父工程的build.gradle配置父工程的settings.gradle配置创建支付子工程(payment_nativ…

物联网开发笔记(64)- 使用Micropython开发ESP32开发板之控制ILI9341 3.2寸TFT-LCD触摸屏进行LVGL图形化编程:控件显示

一、目的 这一节我们学习如何使用我们的ESP32开发板来控制ILI9341 3.2寸TFT-LCD触摸屏进行LVGL图形化编程&#xff1a;控件显示。 二、环境 ESP32 ILI9341 3.2寸TFT-LCD触摸屏 Thonny IDE 几根杜邦线 接线方法&#xff1a;见前面文章。 三、滑杆代码 import lvgl as lv i…

北京理工大学汇编语言复习重点

汇编是半开卷&#xff0c;可以带纸质资料。理论上&#xff0c;学好了以后&#xff0c;带本书进去就ok了&#xff0c;但是这次是线上&#xff0c;我还没书&#xff0c;就对着考试重点整理一点资料用于打印吧。 因为是线上&#xff0c;所以第4章基本不考框架了&#xff0c;浮点操…

工业4.0,科技引发产业革命,MES系统是数字化工厂的核心

当前&#xff0c;把握工业4.0时代信息技术引发的产业革命风口期&#xff0c;促进产业数字化转型升级&#xff0c;构建产业竞争新格局&#xff0c;实现弯道超车是难得一遇的大好时机&#xff0c;是局势所趋。在这样的大环境下&#xff0c;顺应全世界产业革命趋势&#xff0c;将数…

python的安装

python可以在所有操作系统上运行&#xff0c;但不同操作系统的安装方法有所不同 以&#xff1a;Mac OS X 和 Windows为例 为了安装 Python 并能正常使用&#xff0c;请根据你的操作系统安装提示&#xff0c;按照相应的步骤来操作。 我们还将进行一系列的测试&#xff0c;确保一…

SpringBoot实战(十)集成多数据源dynamic-datasource

目录1.Maven依赖2. DS注解3.普通Hihari连接池3.1 yml配置4.Druid连接池4.1 Druid依赖4.2 yml配置4.3 排除原生的Druid配置5. UserController6. UserServiceImpl7.测试7.1 新增数据7.2 查询数据7.3 测试结果8.源码地址&#xff1a;dynamic-datasource-spring-boot-starter 是一个…

【大数据入门核心技术-Kafka】(四)Kafka常用shell命令

目录 一、准备工作 1、Zookeeper集群安装 2、Kafka集群安装 二、常用Shell命令 1、创建Topic 2、查看创建的Topic 3、查看某一个Topic的详细信息 4、修改Topic 5、删除Topic 6、生产者发布消息命令 7、消费者接受消息命令 8、查看kafka节点数目 9、查看kafka进程 一…

再学C语言8:数据类型(6)——float和其他类型

一、_Bool类型 _Bool类型由C99引入 _Bool类型用于表示布尔值&#xff1a;逻辑值true&#xff08;真&#xff09;和false&#xff08;假&#xff09; C用值1表示true&#xff0c;用值0表示false&#xff0c;所以_Bool类型本质上也是一种整数类型 二、float、double和long do…

查找排序编程题——二分查找+冒泡排序‍♀️

目录 7-1 二分查找 输入格式: 输出格式: 输入样例: AC&#xff1a; 7-2 冒泡法排序 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; AC&#xff1a; 附&#xff1a; 分享&#x1f31e; &#xff1a; 前途与玫瑰 来日与方…

尝试使用LTTng+TraceCompass分析一下进程周期偏移

准备工作 我先是在板子里通过LTTng Stream的方式将log保存在了上位机里。 然后在上位机中打开TraceCompass分析log。 导出整理log数据 然后我在events表格中搜索我的进程名&#xff0c;发现主要是sched_switch sched_waking sched_wakeup这三类。 然后我又搜索了一下&#x…

10个最好的WordPress RSS插件比较(2022)

您是否正在为您的网站寻找最好的 WordPress RSS 提要插件&#xff1f; RSS 提要插件可以轻松地自动从其他网站提取内容并将其显示在您的网站上。它们还可用于提高参与度、增加流量和增加页面浏览量。 在本文中&#xff0c;我们将分享我们挑选的可在您的网站上使用的最佳 Word…

远眺捷码智慧乡村方案赋能乡村治理,打造更智慧更宜居的乡村

01.智慧乡村治理重要性 “智慧乡村”是以云计算、大数据应用、地理信息系统网络、物联网技术为核心&#xff0c;通过构建服务于政务管理、农业增收、民生幸福等方面的系统应用平台&#xff0c;将社会基础信息、产业发展、环境监测、医疗卫生、劳动保障、社会管理、公共服务等要…

全面便捷的数据管理能力,助力数据运营降本增效

对于任何企业来说&#xff0c;销售和供应链总是天平秤座的两端。如何放置两个砝码是对企业管理能力的极大考验。今天&#xff0c;让我们来谈谈供应链管理的例子来探讨一下对于报表工具而言&#xff0c;怎么样才能让客户全面、便捷的全局管理数据接入。背景&#xff1a;有序的供…

SPRING-了解4-AOP1

主要理念&#xff1a;不用继承&#xff0c;而是用Java Reflect类中的Proxy来实现对方法的增强 面向切面编程 oop的延续&#xff0c;对业务进行隔离&#xff0c;降低耦合度&#xff0c;目标是不改变原来的代码在主干中增加新功能 比如已经写好登录功能&#xff0c;现在需要加…

【大数据技术】流数据、流计算、Spark Streaming、DStream的讲解(图文解释 超详细)

流数据和流计算 在大数据时代&#xff0c;数据可以分为静态数据和流数据&#xff0c;静态数据是指在很长一段时间内不会变化&#xff0c;一般不随运行而变化的数据。流数据是一组顺序、大量、快速、连续到达的数据序列&#xff0c;一般情况下数据流可被视为一个随时间延续而无…

脑白质WM中的血流动力学响应函数HRF的特性

血流动力学响应函数HRF 估计BOLD信号的血流动力学响应函数(HRF)对于解释和分析与事件相关的fMRI数据至关重要广义线性模型(GLM)假设BOLD信号是真实反应与HRF进行卷积而得到的 一般来说&#xff0c;白质中功能激活的检测灵敏度远低于灰质&#xff0c;并且激活区域一般较小 原因…

[附源码]Nodejs计算机毕业设计健身房管理系统设计Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…