【Java多线程】Thread类的基本用法

news2024/11/28 14:49:26

目录

Thread类

1、创建线程

1.1、继承 Thread,重写run

1.2、实现 Runnable,重写run

1.3、使用匿名内部类,继承 Thread,重写run

1.4、使用匿名内部类,实现 Runnable,重写run

1.5、使用 lambda 表达式(最常用)

2、终止线程

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

2.2、调用 interrupt() 方法来通知 

3、等待线程

4、获取线程实例

Thread类

 

1、创建线程

线程的创建方法一共有五种,其中lambda表达式的创建方式最为常用,这里简单的给大家介绍一下这五种创建。

1.1、继承 Thread,重写run

class MyThread2 extends Thread {   //创建一个类继承Thread,并重写run
    @Override
    public void run() {   
        System.out.println("hello thread");
    }
}

public class ThreadDemo2 {
    public static void main(String[] args) {
        Thread t = new MyThread2();   //创建MyThread类的实例
        t.start();   //调用start方法启动线程
    }
}

1.2、实现 Runnable,重写run

Thread(Runnable target),使用runnable对象创建线程对象。

class MyThread3 implements Runnable {   //实现Runnable接口
    @Override
    public void run() {
        System.out.println("hello runnable");
    }
}

public class ThreadDemo3 {
    public static void main(String[] args) {
        Runnable runnable = new MyThread3();  //创建runnable对象
        Thread t = new Thread(runnable);   //将runnable对象作为target参数
        t.start();   //start启动线程
    }
}

1.3、使用匿名内部类,继承 Thread,重写run

public class ThreadDemo4 {
    public static void main(String[] args) {
        Thread t = new Thread() {   //继承thread类的匿名内部类
            @Override
            public void run() {
                System.out.println("hello thread");
            }
        };
        t.start();
    }
}

1.4、使用匿名内部类,实现 Runnable,重写run

public class ThreadDemo5 {
    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {   //实现Runnable接口的匿名内部类
            @Override
            public void run() {
                System.out.println("hello runnable");
            }
        });
        t.start();
    }
}

1.5、使用 lambda 表达式(最常用)

public class ThreadDemo6 {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {   //实现Runnable接口重写run的lambda写法【推荐使用】
            System.out.println("hello thread");
        });
        t.start();
    }
}

2、终止线程

有时我们需要让正在执行的线程终止,为了让线程能够停止,需要添加一些机制。

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

public class ThreadInterrupt {
        
    public static boolean isQuit = false;   //设置标志位isQuit充当控制开关

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            while (!isQuit) {    //控制while终止
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);   //让每个打印间隔1秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("线程执行完毕");
        });
        t.start();
        Thread.sleep(3000);   //sleep睡眠3秒后再修改标志位
        isQuit = true;
    }
}

2.2、调用 interrupt() 方法来通知 

        使用 Thread.interrupted() 或者 Thread.currentThread().isInterrupted() 代替自定义标识位。

        其中,Thread.currentThread() 表示获取当前线程实例,类似于 this 。而这里没有直接使用this是因为此处的Thread线程使用的是匿名内部类,无法通过this获取当前实例。

        最后使用 interrupt() 进行终止线程。

    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);   //让每个打印间隔1秒
                } catch (InterruptedException e) {
                    break;   //注意此处需要添加break,因为sleep会清空interrupted标志位
                }
            }
            System.out.println("线程执行完毕");
        });
        t.start();
        Thread.sleep(3000);   //sleep睡眠3秒后再调用interrupt终止线程
        t.interrupt();
    }

3、等待线程

多个线程的执行顺序是不确定的(随机调度,抢占式执行)

虽然线程底层的调度是随机的,但是可以在应用程序中,通过一些api,来影响到线程的调度顺序使用join就是其中一种方式,join()方法可以确定线程的结束顺序


    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {   
            System.out.println("hello thread1");
        });
        Thread t2 = new Thread(() -> {   
            System.out.println("hello thread2");
        });
        t1.start();   //此时t1线程开始执行
        t1.join();    //等待t1结束后再执行下面代码

        t2.start();   //此时t2线程开始执行
        t2.join();    //等待t2结束后再执行下面代码
        System.out.println("hello main");   //最后执行main主线程中的打印
    }

【谁调用,谁等待】main方法中调用t.join(),main主线程就阻塞等待t线程结束,再继续执行。

典型的使用场景:
使用多个线程并发进行一系列计算,用一个线程阻塞等待上述计算线程,等到所有的线程都计算完了,最终这个线程汇总结果。

4、获取线程实例

有两种获取线程实例的方法,一种是 this ,另一种是 Thread.currentThread() 。

其中需要注意的是:this不能使用到匿名内部类中,因此匿名内部类只能通过Thread.currentThread() 来获取实例。

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("MyThread :"+this.getName());   //使用this直接获取实例
    }
}
public class GetThread {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            Thread thread = Thread.currentThread();   //匿名内部类中通过currentThread获取实例
            System.out.println("t1线程中: "+thread.getName());

        });
        Thread t2 = new MyThread();
        
        t1.start();
        t1.join();
        
        t2.start();
    }
}

 

 

【博主推荐】 

对进程与线程的理解-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/136115808?spm=1001.2014.3001.5501【数据结构】二叉树的三种遍历(非递归讲解)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/136044643?spm=1001.2014.3001.5501【LeetCode力扣】单调栈解决Next Greater Number(下一个更大值)问题-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/136030138?spm=1001.2014.3001.5501

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

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

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

相关文章

问题:总离差平方和为变形观测值与变形观测值的平均值之差的平方和。() #微信#其他

问题:总离差平方和为变形观测值与变形观测值的平均值之差的平方和。() 是 否 参考答案如图所示

html的表格标签

html的表格标签 table标签:表示整个表格tr:表示表格的一行td:表示一个单元格th:表示表头单元格.会居中加粗thead:表格的头部区域 (注意和th区分,范围是比th要大的).tbody:表格得到主体区域. table包含tr , tr包含td或者th. 表格标签有一些属性,可以用于设置大小边…

ChatGPT高效提问—prompt实践(健康助手)

ChatGPT高效提问—prompt实践(健康助手) ​ 随着社会经济的发展,人们的生活条件不断改善,人们对身体健康也日益重现。让ChatGPT作为健康助手也是一件不错的事。开始之前,还是老样子,先设置角色。 ​ 输入…

Typora+PicGO+腾讯云COS做图床教程

文章目录 Typora+PicGO+腾讯云COS做图床教程一、为什么使用图床二、Typora、PicGO和腾讯云COS介绍三、下载Typora和PicGOTyporaPicGO 四、配置Typora、PicGO和腾讯云COS腾讯云COS配置PicGO配置Typora配置 Typora+PicGO+腾讯云COS做…

【MySQL】操作库 —— 表的操作 -- 详解

一、增加表 1、创建表 mysql> create database [if not exists] table_name ( -> field1 datatype, -> field2 datatype, -> field3 datatype -> ) character set 字符集 collate 校验规则 engine 存储引擎; 注意 :最后一行也可以写成&#x…

中国电子学会2023年12月份青少年软件编程Scratch图形化等级考试试卷一级真题(含答案)

2023-12 Scratch一级真题 分数:100 题数:37 测试时长:60min 一、单选题(共25题,共50分) 1.观察下列每个圆形中的四个数,找出规律,在括号里填上适当的数?(C)&#xf…

C语言操作符练习

练习开胃菜 曾经有一道面试题&#xff0c;要求不能创建临时变量&#xff08;第三个变量&#xff09;&#xff0c;实现两个数的交换。 这道题如果没有前半句的修饰&#xff0c;就只是简单的一道基础题。 法一&#xff1a; #include <stdio.h> int main() {int a 0;i…

网络安全威胁,如何解决缓冲区溢出攻击

目录 一、什么是网络安全 二、什么是缓冲区 三、缓冲区溢出 四、缓冲区溢出攻击的类型 一、什么是网络安全 网络安全&#xff08;Network Security&#xff09;指的是保护计算机网络及其相关设备、系统和数据免受未经授权访问、破坏、篡改、窃取或滥用的威胁和攻击。随着网…

生成式AI相关知识记录

一、简述开发步骤 开发一个生成式AI模型通常涉及以下步骤&#xff1a; 1. **需求分析与目标设定**&#xff1a; - 确定应用领域和目标&#xff0c;例如文本生成、图像生成、音乐创作等。 - 分析应用场景的具体需求&#xff0c;包括输出质量、速度、多样性、可控性等因素…

Codeforces Round 926 (Div. 2)

Codeforces Round 926 (Div. 2) Codeforces Round 926 (Div. 2) A. Sasha and the Beautiful Array 题意&#xff1a;略。 思路&#xff1a;从小到大排序&#xff0c;取前后差和。 AC code&#xff1a; void solve() {int ans 0;cin >> n;for (int i 1; i < n…

云原生之容器编排-Docker Swarm

1. 前言 上一篇我们讲到Docker Compose可以定义和运行多容器应用程序&#xff0c;用一个YAML配置文件来声明式管理服务&#xff0c;在一台安装了Docker engine的Linux系统上可以很好的工作&#xff0c;但是现实中不可能只有一台Linux系统&#xff0c;一台Linux系统不可能有足够…

算法详解(力扣141——环形链表系列)

博主ID&#xff1a;代码小豪 文章目录 环形链表环形链表的性质分析快慢指针法指针的追及相遇问题 环形链表&#xff08;2&#xff09; 环形链表 先来看看环形链表的原题&#xff1a; 中间的部分叙述有点繁杂&#xff0c;简单来概括就是&#xff0c;假如有一个节点&#xff0c…

C语言:指针的基础详解

目录 1. 内存 2. 取地址& 3. 指针变量 4. 解引用 4.1 *解引用 4.2 []解引用 4.3 ->解引用 5. 指针变量的大小 5.1 结论 6. 指针运算 7. void* 指针 8. const修饰指针 8.1 const修饰变量 8.2 const修饰指针变量 8.3 结论 9. 野指针 9.1 为什么会出现野指…

【AIGC】Stable Diffusion的模型微调

为什么要做模型微调 模型微调可以在现有模型的基础上&#xff0c;让AI懂得如何更精确生成/生成特定的风格、概念、角色、姿势、对象。Stable Diffusion 模型的微调方法通常依赖于您要微调的具体任务和数据。 下面是一个通用的微调过程的概述&#xff1a; 准备数据集&#xf…

optuna,一个好用的Python机器学习自动化超参数优化库

🏷️个人主页:鼠鼠我捏,要死了捏的主页 🏷️付费专栏:Python专栏 🏷️个人学习笔记,若有缺误,欢迎评论区指正 前言 超参数优化是机器学习中的重要问题,它涉及在训练模型时选择最优的超参数组合,以提高模型的性能和泛化能力。Optuna是一个用于自动化超参数优化的…

数据密集型应用系统设计

数据密集型应用系统设计 原文完整版PDF&#xff1a;https://pan.quark.cn/s/d5a34151fee9 这本书的作者是少有的从工业界干到学术界的牛人&#xff0c;知识面广得惊人&#xff0c;也善于举一反三&#xff0c;知识之间互相关联&#xff0c;比如有个地方把读路径比作programming …

springboot192中国陕西民俗网

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的中国陕西民俗网 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取…

2.15日总结

第一题&#xff1a;最小生成树 #include<bits/stdc.h> using namespace std; int n,m; //输入n个节点以及m条边 struct lu//结构体 {int start;//连接到第一个节点int end1;//第二个节点long long l;//输入图之间的距离 }a[2000005]; int f[100005]; long long sum;//最小…

【硬核】javascript轻松实现自动化批量取消某音用户关注功能

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起学习和进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&a…

JDBC教程+数据库连接池

JDBC 1.JDBC概述 ​ JDBC&#xff0c;全称Java数据库连接&#xff08;Java DataBase Connectivity&#xff09;&#xff0c;它是使用Java语言操作关系型数据库的一套API。 ​ JDBC本质是官方&#xff08;原SUN公司&#xff0c;现ORACLE&#xff09;定义的一套操作所有关系型数…