JavaEE之线程(3)_线程的开始、中断、等待、休眠线程、线程的状态

前言

 在本栏的上一节(https://blog.csdn.net/2301_80653026/article/details/138500558),我们重点讲解了五种不同的创建线程的方式,我们还介绍了Tread类的常见构造方法和常见属性,在这一节中我们将会继续介绍Tread类。


一、启动一个线程 start( )

 在上一节我们讲解了如何通过覆写 run 方法创建一个线程对象,但线程对象被创建出来并不意味着线程就开始运行了。比如:

  1. 覆写 run 方法是提供给线程要做的事情的指令清单
  2. 线程对象可以认为是把 李四、王五叫过来了
  3. 而调用 start( ) 方法,就是喊一声:”行动起来!“,线程才真正独立去执行了

调用 start 方法, 才真的在操作系统的底层创建出一个线程。
Thread类中run和start的区别:

作用功能不同:
 1. run方法的作用是描述线程具体要执行的任务;
 2. start方法的作用是真正的去申请系统线程
.运行结果不同:
 1. run方法是一个类中的普通方法,主动调用和调用普通方法一样,会顺序执行一次;
 2. start调用方法后, start方法内部会调用Java 本地方法(封装了对系统底层的调用)真正的启动线程,并执行run方法中的代码,run 方法执行完成后线程进入销毁阶段

参考示例代码:

/**
 * @author Zhang
 * @date 2024/4/2915:16
 * @Description:
 */

//创建一个类,继承自Thread
class  MyThread extends  Thread{
    //这个方法就是线程的入口方法
    @Override
    public void run() {
       // System.out.println("hello Thread");
       
        while(true){
            System.out.println("hello threat");
            try {
                Thread.sleep(1000);  //休眠1000毫秒
                /**
                 * 此处必须try catch,不能throws
                 * 在这个代码中重写的是父类的run,父类的run没有throws,因此,子类方法也就不能有throws
                 */
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }
}

//创建线程
public class Demo1 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new MyThread();
        //start 和run都是Threat的成员
        //run只是描述了线程的入口(线程要做生么任务)
        //start 则是真正调用了系统API,在系统中创建线程,让线程再调用run
        t.start();

         while(true){
         System.out.println("hello main");
         Thread.sleep(1000);  //休眠1000毫秒
         }
    }
}

二、中断一个线程

停止一个线程主要有以下两种方式:

2.1 通过共享的标记来进行沟通

参考实例代码:

/**
 * @author Zhang
 * @date 2024/5/415:58
 * @Description:
 */
public class Demo8 {
    private  static  boolean isQuit = false;  //成员变量
    public static void main(String[] args) throws InterruptedException {
       //  boolean isQuit = false; 不能使用局部 变量
        Thread t=  new Thread(()->{
            while(!isQuit){
                //
                System.out.println("线程工作中");
                //此处的打印可以替换成任意的逻辑来表示逻辑的实际工作内容
                  try {
                       Thread.sleep(1000);
                  } catch (InterruptedException e) {
                      throw new RuntimeException(e);
                  }
              }
            System.out.println("线程作完毕");
        });
        t.start();
        Thread.sleep(5000);
        isQuit = true;
        System.out.println("设置 isQuit 为 true");

    }
}

2.2 调用interrupt( )方法来通知

 使用 Thread.interrupted() 或Thread.currentThread().isInterrupted() 代替自定义标志位。其中,Thread 内部包含了一个 boolean 类型的变量作为线程是否被中断的标记。
在这里插入图片描述
使用 thread 对象的 interrupted() 方法通知线程结束的代码参考实例:

public class ThreadDemo {
	private static class MyRunnable implements Runnable {
		@Override
		public void run() {
		// 两种方法均可以
			while (!Thread.interrupted()) {
				//while (!Thread.currentThread().isInterrupted()) {
				System.out.println(Thread.currentThread().getName()
				+ ": 别管我,我忙着转账呢!");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				System.out.println(Thread.currentThread().getName()
				+ ": 有内鬼,终止交易!");
				// 注意此处的 break
				break;
				}
			}
			System.out.println(Thread.currentThread().getName()
	+ ": 啊!险些误了大事");
		}
	}
------------------------------------------------------------------
	public static void main(String[] args) throws InterruptedException 		{
		MyRunnable target = new MyRunnable();
		Thread thread = new Thread(target, "李四");
		System.out.println(Thread.currentThread().getName()
		+ ": 让李四开始转账。");
		thread.start();
		Thread.sleep(10 * 1000);
		System.out.println(Thread.currentThread().getName()
		+ ": 老板来电话了,得赶紧通知李四对方是个骗子!");
		thread.interrupt();
		}
}

thread 收到通知的方式有两种:

  1. 如果线程因为调用 wait/join/sleep 等方法而阻塞挂起,则以InterruptedException 异常的形式,清除中断标志。

当出现 InterruptedException 的时候, 要不要结束线程取决于 catch 中代码的写法, 可以选择忽略这个异常, 也可以跳出循环结束线程

  1. 否则,只是内部的一个中断标志被设置,thread 可以通过

Thread.interrupted() 判断当前线程的中断标志被设置,清除中断标志
Thread.currentThread().isInterrupted() 判断指定线程的中断标志被设置,不清除中断标志

/**
 * @author Zhang
 * @date 2024/5/416:27
 * @Description:
 */
public class Demo9 {

    public static void main(String[] args)  {
        Thread t = new Thread(() ->{
            //Thread类内部,有一个现成的标志位,可以判定当前的循环是否结束
            while(!Thread.currentThread().isInterrupted()){
                System.out.println("线程工作中");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    //throw new RuntimeException(e);
                    //1.假装没听见,循环继续正常执行
                    e.printStackTrace();
                    // 2.加上一个break,表示线程立即结束
                    //break;
                    //3.先做一些其他工作,完成之后再结束
                    //其他工作的代码
                    //break;
                }
            }
        });
        t.start();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("线程终止");
        t.interrupt();
    }
}

三、 等待一个线程join( )

 有时,我们需要等待一个线程完成它的工作后,才能进行自己的下一步工作

参考实例代码:

/**
 * @author Zhang
 * @date 2024/5/416:54
 * @Description:
 */
public class Demo10 {
    public static void main(String[] args) throws InterruptedException {
        Thread t =  new Thread(()->{
           for (int i = 0; i<5;i++ ){
               System.out.println("t 线程工作中");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
           }
        });
        t.start();

        //让主线程等待t线程执行结束
        //一旦调用join,主线程就会出发阻塞。此时t线程就可以趁机完成后续的工作
        //一直阻塞到 t 执行完毕了, join才会解除阻塞,才能继续执行
        System.out.println("join 等待开始");
        t.join();
        //t.join 工作过程:
        //   1)如果t线程正在运行中,此时调用 join 的线程就会阻塞, 一直阻塞到t线程执行结束为止
        //   2)如果t线程已经执行结束了,此时调用 join 线程,就直接返回了,不会涉及到阻塞~~
        System.out.println("join 等待结束");
    }
}

其他一些 join( )方法

四、获取当前线程引用 和 休眠当前线程

4.1 获取当前线程引用

常见方法:public static Thread currentThread(); ——返回当前线程对象的引用
参考代码实例

public class ThreadDemo {
	public static void main(String[] args) {
		Thread thread = Thread.currentThread();
		System.out.println(thread.getName());
	}
}

4.2 休眠当前线程

public class ThreadDemo {
	public static void main(String[] args) throws InterruptedException {
		System.out.println(System.currentTimeMillis());
		Thread.sleep(3 * 1000);
		System.out.println(System.currentTimeMillis());
	}
}

五、 线程的状态

在这里插入图片描述
在这里插入图片描述

总结

 好啦!以上就是今天要讲的内容,本文介绍了Thread类的start( )方法、线程的的中断、等待一个线程join( )、获取当前线程的引用,休眠当前线程,以及线程的引用。在本栏的下一节我们将会继续介绍Thread中重点内容——线程安全。

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

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

相关文章

【SVN-TortoiseSVN】SVN 的简介与TortoiseSVN 安装使用教程

目录 &#x1f31e;前言 &#x1f30a;1. SVN 的简介 &#x1f30d;1.1 SVN是什么 &#x1f30d;1.2 SVN 工作原理 &#x1f30d;1.3 TortoiseSVN 术语及定义 &#x1f30a;2. TortoiseSVN 安装与汉化 &#x1f30a;3. SVN 基本操作-TortoiseSVN &#x1f30d;3.1 浏览…

在k8s中部署Prometheus并实现对k8s集群的监控

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Prometheus&#xff1a;监控的神》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、k8s简介 2、 Prometheus概述 二、准备k8s环境 1、…

C语言:__attribute__((packed))

一、简介 在使用结构体的时候&#xff0c;经常要根据结构体的长度来进行相关判断。但是按照C语言的规则&#xff0c;会对不同类型的数据类型进行自动对齐。有时候就会造成一些问题&#xff0c;如果不需要使用自动对齐的功能&#xff0c;就需要使用到本章的关键字。 二、自动对…

fabric搭建生产网络

fabric搭建生产网络 一、生成组织结构与身份证书 解包 hyperledger-fabric-linux-amd64-2.5.0.tar.gz 1.1、crypto-config.yaml配置文件 ./bin/cryptogen showtemplate > crypto-config.yaml 将crypto-config.yaml内容修改为&#xff1a; # -------------------------…

Django 管理员登录安全 OTP双因素认证

目前安全双因素 最基本的&#xff0c;django管理员 默认直接登录的。 本项目环境:Django 2.0.13django-otp 0.9.3 1 安装pip3 install django-otp0.9.3 2 配置文件 vim api_statistics/settings.py INSTALLED_APPS里增加django_otp,django_otp.plugins.otp_totp,MIDDLEWARE…

推荐几款国内的AI写作工具,好用免费还能在线生成AI文案

AI写作简介&#xff1a; 在专业领域中&#xff0c;人工智能技术的进步正以前所未有的速度推动着写作行业的革新。当前&#xff0c;我们见证了生成式人工智能&#xff08;AI&#xff09;在文本产生领域的广泛应用&#xff0c;其对提升创作效率和拓展创意边界的贡献是显著的。以…

用 Next.js 和 Supabase 进行“全栈”开发的入门

文章目录 &#xff08;零&#xff09;前言&#xff08;一&#xff09;创建Next.js应用程序&#xff08;1.1&#xff09;新建工程目录&#xff08;1.2&#xff09;安装依赖环境&#xff08;1.3&#xff09;创建Tailwind配置 &#xff08;二&#xff09;创建Supabase项目&#xf…

Leetcode—232. 用栈实现队列【简单】

2024每日刷题&#xff08;131&#xff09; Leetcode—232. 用栈实现队列 实现代码 class MyQueue { public:MyQueue() {}void push(int x) {st.push(x);}int pop() {if(show.empty()) {if(empty()) {return -1;} else {int ans show.top();show.pop();return ans;}} else {i…

管道液位传感器怎么接线

管道光电液位传感器是用来检测水管缺水的一种液位传感器&#xff0c;有水无水输出不同电压信号&#xff0c;在洗地机领域有着广泛的应用&#xff0c;那么管道液位传感器怎么接线&#xff1f; 管道液位传感器通常有三根线&#xff0c;电源线、地线和信号线&#xff0c;电源线接…

window golang 升级版本

执行go tidy&#xff0c;发现执行不了&#xff0c;得升级一下版本了 进入官网&#xff0c;并选择合适的系统以及版本。https://go.dev/dl/ 这台电脑是windows&#xff0c;我本人比较喜欢下载zip自己解压。 解压&#xff0c;这里我选择直接覆盖原文件&#xff0c;需要保留原版…

2024智能电网与能源系统国际学术会议(ICSGES2024)

2024智能电网与能源系统国际学术会议&#xff08;ICSGES2024) 会议简介 我们诚挚邀请您参加将在南京隆重举行的2024年智能电网与能源系统国际学术会议&#xff08;ICSGES2024&#xff09;。南京&#xff0c;一座历史与现代交织的城市&#xff0c;将为这场盛会提供独特的学术…

AVL树的原理及其实现

文章目录 前言了解AVL树AVL树的特点AVL树的节点调整方案右单旋为什么要右单旋呢&#xff1f;右单旋代码 左单旋为什么要左单旋&#xff1f;左单旋代码 左右双旋左右双旋之后平衡因子的情况左右双旋代码实现 右左双旋右左双旋代码&#xff1a; 简单测试 前言 回顾我们对于二叉搜…

HarmonyOS开发案例:【生活健康app之实现打卡功能】(2)

实现打卡功能 首页会展示当前用户已经开启的任务列表&#xff0c;每条任务会显示对应的任务名称以及任务目标、当前任务完成情况。用户只可对当天任务进行打卡操作&#xff0c;用户可以根据需要对任务列表中相应的任务进行点击打卡。如果任务列表中的每个任务都在当天完成则为…

基于 AI 的 Python 爬虫

✦ 支持 OPENAI、Gemini、Groq、本地 Ollama、Azure 等 LLM ✦ 只需传递 Prompt 和链接 注意&#xff1a; 调用 Ollama 模型&#xff0c;需要运行下方指令&#xff0c;拉取 embedding 模型&#xff1a; ollama pull nomic-embed-text 问题&#xff1a; 似乎不能换成兼容 Ope…

进程间通信 管道

前言 ubuntu系统的默认用户名不为root的解决方案&#xff08;但是不建议&#xff09;&#xff1a;轻量应用服务器 常见问题-文档中心-腾讯云 (tencent.com) 进程间通信的基本概念 进程间通信目的&#xff1a;进程间也是需要协同的&#xff0c;比如数据传输、资源共享、通知事件…

人脸图像生成(DCGAN)

一、理论基础 1.什么是深度卷积对抗网络&#xff08;Deep Convolutional Generative Adversarial Network&#xff0c;&#xff09; 深度卷积对抗网络&#xff08;Deep Convolutional Generative Adversarial Network&#xff0c;DCGAN&#xff09;是一种生成对抗网络&#xf…

计算机通信SCI期刊推荐,JCR1区,IF=6+,审稿快,无版面费!

一、期刊名称 Computer Communications 二、期刊简介概况 期刊类型&#xff1a;SCI 学科领域&#xff1a;计算机科学 影响因子&#xff1a;6 中科院分区&#xff1a;3区 出版方式&#xff1a;订阅模式/开放出版 版面费&#xff1a;选择开放出版需支付$2300 三、期刊征稿…

STM32中的ICACHE是什么有什么用?如何使用?

什么是ICACHE&#xff1f; icache是一种用于缓存指令的存储器&#xff0c;其目的是提高CPU执行指令的效率。 在计算机系统中&#xff0c;icache&#xff08;指令缓存&#xff09;是处理器核心内部的一个关键组件&#xff0c;它专门用来存储最近使用过的指令。当CPU需要执行一个…

Bean的作用域

Bean的作用域 Bean的作用域是指在Spring整个框架中的某种行为模式&#xff0c;比如singleton单例作用域&#xff0c;就表示Bean在整个spring中只有一份&#xff0c;它是全局共享的&#xff0c;那么当其他人修改了这个值时&#xff0c;那么另一个人读取到的就是被修改的值 Bea…

每日OJ题_记忆化搜索②_力扣62. 不同路径(三种解法)

目录 力扣62. 不同路径 解析代码1_暴搜递归&#xff08;超时&#xff09; 解析代码2_记忆化搜索 解析代码3_动态规划 力扣62. 不同路径 62. 不同路径 难度 中等 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器…