Thread类的基本用法

⭐ 作者:小胡_不糊涂
🌱 作者主页:小胡_不糊涂的个人主页
📀 收录专栏:JavaEE
💖 持续更文,关注博主少走弯路,谢谢大家支持 💖

Thread

  • 1. 线程创建
    • 1.1 继承Thread类
    • 1.2 实现Runnable接口
    • 1.3 使用匿名内部类创建Thread子类对象
    • 1.4 使用匿名类创建 Runnable 子类对象
    • 1.5 使用lambda 表达式
  • 2. 线程中断
    • 2.1 使用自定义的变量来作为标记位
    • 2.2 调用interrupt()方法来通知
  • 3. 线程等待-join()
  • 4. 线程休眠-sleep()
  • 5. 获取线程实例

在这里插入图片描述

1. 线程创建

1.1 继承Thread类

class MyThread extends Thread{
    public void run(){
        System.out.println("继承Thread,重写run");
    }
}
public class TestDemo1{
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start();//启动线程
    }
}

1.2 实现Runnable接口

class MyRunnable implements Runnable{
    public void run(){
        System.out.println("实现Runnable接口");
    }
}
public class TestDemo1{
    public static void main(String[] args) {
        Thread thread=new Thread(new MyRunnable());
        thread.start();
    }
}

1.3 使用匿名内部类创建Thread子类对象

public class TestDemo1{
    public static void main(String[] args) {
        Thread thread=new Thread(){
            public void run(){
                System.out.println("这是一个线程");
            }
        };
        thread.start();
    }
}

1.4 使用匿名类创建 Runnable 子类对象

public class TestDemo1{
    public static void main(String[] args) {
        Thread thread=new Thread(new Runnable(){
            public void run() {
                System.out.println("实现Runnable,重写run,使用匿名内部类");
            }
        });
        thread.start();//启动线程
    }
}

1.5 使用lambda 表达式

public class TestDemo1{
    public static void main(String[] args) {
        Thread thread=new Thread(()->{
                System.out.println("使用lambda表达式");
        });
        thread.start();
    }
}

2. 线程中断

当我们想要让一个正在执行的线程停止时,该怎么做呢?

2.1 使用自定义的变量来作为标记位

ublic class TestDemo2 {
    private static volatile boolean isquit=false;
    public static void main(String[] args) {
        Thread thread=new Thread(()->{
            while(!isquit){
                System.out.print(Thread.currentThread().getName());
                System.out.println("线程工作中...");
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            //线程运行完毕
            System.out.println("线程工作完毕");
        });
        thread.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        isquit = true;
        System.out.println("让 thread 线程结束!");
    }
}

需要给标志位上加 volatile 关键字才能进行修改

2.2 调用interrupt()方法来通知

方法说明
public void interrupt()中断对象关联的线程
public static boolean interrupted()判断当前线程的中断标志位是否设置
public bool isInterrupted()判断对象关联的线程标志位是否设置
public class TestDemo2 {
    public static void main(String[] args) throws InterruptedException {
        Thread thread=new Thread(()-> {
            //while(!Thread.interrupted()){
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("线程工作中...");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    break;
                }
            }
        });
        thread.start();
        Thread.sleep(2000);
        // 使用一个 interrupt 方法, 来修改刚才标志位的值
        System.out.println("让 thread 线程结束");
        thread.interrupt();
    }
}

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

  1. 如果线程因为调⽤ wait/join/sleep 等⽅法⽽阻塞挂起,则以 InterruptedException 异常的形式通知,清除中断标志。
    当出现 InterruptedException 的时候,要不要结束线程取决于catch 中代码的写法。可以选择忽略这个异常,也可以跳出循环结束线程。
  2. 否则,只是内部的⼀个中断标志被设置,thread 可以通过。
    Thread.currentThread().isInterrupted()判断指定线程的中断标志被设置,不清除中断标志,这种方式通知收到的更及时,即使线程正在 sleep 也可以马上收到。

3. 线程等待-join()

有时,我们需要等待⼀个线程完成它的⼯作后,才能进⾏⾃⼰的下⼀步⼯作。

public class TestDemo3{
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            int n = 5;
            for (int i = 0; i < n; i++) {
                System.out.println("我是一个线程, 正在工作中...");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("线程执行结束");
        });

        t.start();
        t.join();  // 线程等待
        System.out.println("这是主线程, 期望在 thread 结束后打印");
    }
}

在这里插入图片描述

如果将t.join()注释,结果会是什么呢?
在这里插入图片描述

方法说明
public void join()等待线程结束
public void join(long millis)等待线程结束,最多等待millis毫秒
public void join(long millis,int nanos)同上

4. 线程休眠-sleep()

为线程的调度是不可控的,所以,该⽅法只能保证实际休眠时间是⼤于等于参数设置的休眠时间的。

方法说明
public static void sleep(long millis) throws InterruptedException休眠当前线程run方法
public static void sleep(long millis,int nanos) throws InterruptedException可以更高精度的休眠线程
public class TestDemo4 {
    public static void main(String[] args) throws InterruptedException {
        Thread t1=new Thread(()->{
            System.out.println("t1正在执行");
        });
        Thread t2=new Thread(()->{
            System.out.println("t2正在执行");
        });
        t1.start();
        t2.start();
    }
}

上面的执行过程中,我们无法控制t1与t2的先后执行顺序,运行时就会产生:
在这里插入图片描述

但是当我们让main线程在执行t1线程时,进入有限的休眠状态,就可以保证t2不会来干扰t1

public class TestDemo4 {
    public static void main(String[] args) throws InterruptedException {
        Thread t1=new Thread(()->{
            System.out.println("t1正在执行");
        });
        Thread t2=new Thread(()->{
            System.out.println("t2正在执行");
        });
        t1.start();
        Thread.sleep(1000);
        t2.start();
    }
}

在这里插入图片描述

5. 获取线程实例

方法说明
public static Thread currentThread();返回当前线程对象的引用
public class TestDemo5 {
    public static void main(String[] args) {
        Thread thread=Thread.currentThread();
        System.out.println(thread.getId());//1
        System.out.println(thread.getName());//main
    }
}
public class TestDemo5 {
    public static void main(String[] args) {
       // Thread thread=Thread.currentThread();
        Thread thread=new Thread();
        System.out.println(thread.currentThread().getId());//1
        System.out.println(thread.getName());//Thread-0
    }
}

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

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

相关文章

arcEngine修改字段标注

修改字段标注 在arcEngine中&#xff0c;有时候需要修改图层要素的标注值&#xff0c;而且每个字段值对应了要修改的内容&#xff0c;如字段值”1“替换成”A“&#xff0c;字段值”2“替换成”B“等&#xff0c;这就需要在替换的图层中&#xff0c;遍历每个要素&#xff0c;查…

LeetCode 21 合并两个有序链表

题目描述 合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示例 2&#xff1a; 输入&#xff1a;l1 [],…

「用户与社区的深度对话」2023年度IvorySQL满意度调研

致IvorySQL社区成员&#xff0c; &#x1f3c3;‍♂️2023年即将进入尾声&#xff0c;感谢每一位社区朋友对IvorySQL的支持。我们诚挚地邀请您参与我们的社区满意度调研。您的反馈对我们至关重要&#xff0c;将有助于改进我们的服务&#xff0c;为您提供更好的社区体验&#xf…

[数据结构进阶 C++] 二叉搜索树(BinarySearchTree)的模拟实现

文章目录 1、二叉搜索树1.1 二叉搜索数的概念1.2 二叉搜索树的操作1.2.1 二叉搜索树的查找1.2.2 二叉搜索树的插入1.2.3 二叉搜索树的删除 2、二叉搜索树的应用2.1 K模型2.2 KV模型 3、二叉搜索树的性能分析4、K模型与KV模型完整代码4.1 二叉搜索树的模拟实现&#xff08;K模型…

设计模式(三)-结构型模式(6)-享元模式

一、为何需要享元模式&#xff08;Flyweight&#xff09;? 假如在网页中渲染这样的一个画面&#xff1a;大小不一的星星铺满了整个画布&#xff0c;并且都在不断的进行移动闪烁着。一批星星消失了&#xff0c;另一批又从另一边缘处出现。 要实现这样的渲染效果&#xff0c;在…

C语言之初识C语言

文章目录 前言一、什么是C语言二、第一个C语言程序三、数据类型四、变量&#xff0c;常量1、变量1.1 变量的命名1.2 变量的分类1.3 变量的使用1.4 变量的作用域和生命周期2、变量 五、字符串1. 概念2. 求解字符串的长度【strlen】3. 转义字符【含笔试题】 六、注释七、选择语句…

ESP8266 TCP/串口透传

简介 先在PC上做测试, 使用串口软件对ESP8266 模块进行设置, 使用网络助手软件与串口软件进行自由收发设置 ATRST ## 复位 ATCWMODE_DEF1 ## 设置为Station模式 ATCWJAP_DEF“路由器wifi名称”,“路由器wifi密码” ## 设置ESP连接的路由器名称密码 ATCIPSTART“TCP”,“192.1…

Alpha突触核蛋白神经退行性疾病

Alpha突触核蛋白科研背景 ● Alpha突触核蛋白约 15kDa, 140个氨基酸 ● StressMarq在E. coli中过表达人源基因然后将蛋白从细胞质基质中纯化出来 ● 未折叠的alpha突触核蛋白单体在12% SDS-PAGE上为~15 kDa的条带 StressMarq/欣博盛生物的Alpha突触核蛋白有以下两类&#xf…

[uni-app] mescroll与 page 本身的滚动冲突处理, 动态禁用下拉刷新

参考贴: uniapp动态禁用mescroll-body组件的下拉刷新,或者动态禁用mescroll-body组件的上拉加载 记录问题场景 如图: 搜索和 第二个标签栏, 都是随页面滚动的, 当页面滚动一定距离, 会触发标签栏的吸顶 即如上图, 问题描述 当列表页面数据部满屏时, 且页面已经由于滚动而吸顶…

许可式邮件营销与垃圾邮件的区别:合规与效果的关键区分

接触过邮件营销的人一定不陌生“垃圾邮件”和“许可式邮件营销”这两个名词。在各大电商节到来之际&#xff0c;小编帮助大家弄清楚什么是垃圾邮件&#xff1f;什么是许可式邮件营销&#xff1f;为什么会变成垃圾邮件&#xff1f;怎么做许可式邮件营销&#xff1f;让大家在促销…

极智嘉(Geek+)货到人方案优势显著,助力拆零场景效率提升

众所周知&#xff0c;零售行业所面临的物流挑战比其他行业更为严峻。这是由于零售行业复杂的行业业态、繁多的商品种类、“唯快主义”的配送需求&#xff0c;以及零售行业的终端客户多为个体消费者&#xff0c;购买习惯以单件、多品为主&#xff0c;购买习惯具有周期性和爆发性…

minio 分布式对象存储

分布式文件系统应用 1.1、Minlo 介绍 Minlo 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口&#xff0c;非常适合于存储大容量非结构化的数据&#xff0c;例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等&#xff0c;而一个对象…

LVM将多个磁盘组成一个逻辑卷实战

LVM&#xff08;Logical Volume Manager&#xff09;是一种逻辑卷管理器&#xff0c;是Linux系统中的一个重要的存储管理技术。它的主要作用是将若干个硬盘分区或者物理硬盘合并成一个逻辑卷组&#xff08;Volume Group&#xff0c;简称VG&#xff09;&#xff0c;然后再将逻辑…

使用Flask逐步搭建Web应用程序

大家好&#xff0c;Flask是一个使用Python编写的轻量级Web应用框架。它被设计成简单、易于学习和使用的&#xff0c;同时具备足够的灵活性和扩展性&#xff0c;以满足各种规模的Web应用开发需求。本文我们将介绍一个使用Flask逐步搭建Web应用程序的简单入门示例。 1.安装Flask…

开发模型和测试模型

1. 开发模型 1.1 瀑布模型 瀑布模型是其他模型的基础框架 start—>需求分析---->计划----->设计----->编码----->测试----->End&#xff08;其实就是软件开发的生命周期&#xff09; 特点&#xff1a;线性的开发流程 缺陷&#xff1a;测试被后置。①风险往…

企业“数据入表”之政策及业务模式解读

2023年8月21日&#xff0c;财政部重磅发布了《企业数据资源相关会计处理暂行规定》&#xff08;以下简称“暂行规定”&#xff09;&#xff0c;该规定将于2024年1月1日正式施行。 “暂行规定”发布后&#xff0c;引起全社会的广泛关注&#xff0c;关注的焦点集中在数据入表概念…

指标体系构建-01-什么是数据指标

参考 四千字全面解析数据产品经理必知概念&#xff1a;标签、维度、指标 什么是数据指标 指标是指于其中打算达到的指数&#xff0c;规格&#xff0c;标准等,是用数据对事物进行描述的工具。通常指标对应是否有价值取决于这个指标的实际意义。同时关注指标对应的数值&#x…

Leetcode 134 加油站

题意理解&#xff1a; 给定n个站点&#xff0c;两个数组gas表达每个站点可加的油量&#xff0c;cost表达到下一站点所需耗费的油量。 gas [1,2,3,4,5], cost [3,4,5,1,2] 要求从下表为i的站点开始&#xff0c;刚好能支撑汽车在每个站点转一圈后回到出发位置。 解题思路&#…

天锐绿盾加密系统是做什么用的?——防止公司内部核心文件数据 \ 资料外泄

天锐绿盾加密系统是一款专业的数据加密软件&#xff0c;主要用于保护企业数据的安全性和完整性。该系统采用先进的加密技术&#xff0c;对数据进行加密处理&#xff0c;确保数据在传输和存储过程中的安全性。 PC访问地址&#xff1a;www.drhchina.com 天锐绿盾加密系统的主要…

RocketMQ系统性学习-RocketMQ高级特性之消息存储在Broker的文件布局

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 【11来了】文章导读地址&#xff1a;点击查看文章导读&#xff01; &#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f3…