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

news2024/10/7 10:13:31

文章目录

  • 线程创建
  • 线程中断
  • 线程等待
  • 线程休眠

线程创建

方法一:用一个类 继承Thread 重写run方法

//创建一个类 继承Thread
class MyThread extends Thread {
    //run方法是线程的入口
    @Override
    public void run() {
        while (true){
            System.out.println("hello Thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

这样一个线程就创建好了,然后可以创建MyThread实例。

public class demo1 {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new MyThread();//向上转型 也可以写成MyThread myThread = new MyThread();
        //运行线程
        thread.start();
        while (true){
            System.out.println("hello main");
            //每1000毫秒打印一次 也就是休眠一秒
            Thread.sleep(1000);
        }
    }
}

方法二:实现 Runnable 接口 重写run方法

class MyRunnable implements Runnable {
    @Override
    public void run() {
        while (true){
            System.out.println("hello Runnable");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

我们可以通过实现Runnable接口来实现创建线程

public class demo2 {
    public static void main(String[] args) throws InterruptedException {
        //runnable表示的是一个可运行的任务 这个任务是交给线程来负责执行的
        Runnable runnable = new MyRunnable();
        Thread t = new Thread(runnable);
        t.start();
        while (true){
            System.out.println("jello main");
            Thread.sleep(1000);
        }
    }
}

方法三:使用匿名内部类,继承Thread 重写run方法

public class demo3 {
    public static void main(String[] args) throws InterruptedException {
        //使用匿名类创建 Thread 子类对象
        Thread t = new Thread(){
            @Override
            public void run() {
                while (true){
                    System.out.println("thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };
        t.start();
        while (true){
            System.out.println("main");
            Thread.sleep(1000);
        }
    }
}

方法四:使用匿名内部类,实现Runnable 重写run方法

public class demo4 {
    public static void main(String[] args) {
        //使用匿名内部类创建 Runnable 子类对象
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    System.out.println("thread");
                }
            }
        });
        t.start();
        while (true){
            System.out.println("main");
        }
    }
}

方法五:使用 lambda 表达式创建 Runnable 子类对象

public class demo5 {
    public static void main(String[] args) {
        //lambda 表达式创建 Runnable 子类对象  
        //lambda 表达式本质上是一个匿名函数
        Thread t = new Thread(()->{
           while (true){
               System.out.println("thread");
           }
        });
        t.setDaemon(true);
        t.start();

    }
}

Thread 类是 JVM 用来管理线程的一个类,换句话说,每个线程都有一个唯一的 Thread 对象与之关联。

创建好线程之后我们可以运行程序观察线程,多线程运行的时候我们可以使用jdk的bin目录下的 jconsole.exe 来观察该进程里多线程的情况。如果运行 jconsole.exe 什么都不显示,就需要以管理员的方式运行。

在这里插入图片描述

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

Thread类的常见构造方法

方法说明
Thread()创建线程对象
Thread(Runnable target)使用 Runnable 对象创建线程对象
Thread(String name)创建线程对象,并命名
Thread(Runnable target, String name)使用 Runnable 对象创建线程对象,并命名

**Thread 的几个常见属性 **

属性获取方法
IDgetId()
名称getName()
状态getState()
优先级getPriority()
是否为后台线程isDaemon()
是否存活isAlive()
是否被中断isInterrupted()
  • ID 是线程的唯一标识,不同线程不会重复
  • 状态就是表示线程当前所处的一个情况
  • 优先级高的线程理论上来说更容易被调度到
  • 关于后台线程也可以叫守护线程,后台线程不结束也不会影响整个线程的结束,但是如果一个前台线程没有执行结束,那么整个进程也一定不会结束(JVM会在一个进程的所有非后台线程结束后,才会结束运行)
  • 是否存活,就是 run 方法是否运行结束

线程中断

在Java里面中断/销毁一个线程其实就是让run尽快执行结束,我们可以在代码中手动创建标志位来作为run的结束条件。

public class demo6 {
    private static boolean isQuit = false;//设置标志位
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            System.out.println("线程正在工作");
            while (!isQuit){
                System.out.println("thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("线程工作结束");
        });
        t.start();
        Thread.sleep(5000);
        isQuit=true;
        System.out.println("hello");
    }
}

运行结果

在这里插入图片描述

上述方法手动创建标志位,当线程内部sleep的时候,,主线程修改变量,新线程不能及时响应,我们就可以使用Thread.currentThread().isInterrupted() 来代替自定义标志位。Thread 内部包含了一个 boolean 类型的变量作为线程是否被中断的标记 。

方法说明
public void interrupt()中断对象关联的线程,如果线程正在阻塞,则以异常方式通知, 否则设置标志位
public static boolean interrupted()判断当前线程的中断标志位是否设置,调用后清除标志位
public boolean isInterrupted()判断对象关联的线程的标志位是否设置,调用后不清除标志位
public class demo7 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            //Thread类内部 有一个标志位 可以用来判断当前的循环是否要结束
            //Thread.currentThread()就是获取当前线程
           while (!Thread.currentThread().isInterrupted()){
               System.out.println("线程正在工作");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
                   //break; //加了break后会立即中断
                   //我们可以加一些其他的代码 然后再break 这样我们可以有更多的操作空间 
               }
           }
        });
        t.start();
        Thread.sleep(5000);
        System.out.println("通过标志位使t线程终止");
        //interrupt可以使sleep内部出现一个异常 从而使线程被提前唤醒 手动创建出的标志位无法达到这个效果
        t.interrupt();//把上述标志位设置为true 即使线程内部出现阻塞 也可以被唤醒 
    }
}

我们观察上面代码的运行结果

在这里插入图片描述

虽然异常出现了,sleep被唤醒但是循环没有终止,t 线程任然在继续工作,并没有停止。Java这样设定是因为,当java收到要中断信息的时候,我们希望它可以自由决定接下来怎么处理。

线程等待

等待一个线程我们使用 join()

public class demo8 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                System.out.println("线程开始工作");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        });
        t.start();
        System.out.println("线程开始等待");
        t.join();//主线程等待 t 线程结束 谁调用join谁是被等的
        System.out.println("等待结束");
    }
}

在这里插入图片描述

一旦调用 join 主线程就会发生阻塞,这样 t 线程就可以完成后面的工作,主线程要一直阻塞到 t 线程执行结束才会解除阻塞。

方法说明
public void join()等待线程结束
public void join(long millis)等待线程结束,最多等 millis 毫秒
public void join(long millis, int nanos)等待线程结束,但可以更高精度 最多等 nanos 纳秒

线程休眠

方法说明
public static void sleep(long millis) throws InterruptedException休眠当前线程 millis 毫秒
public static void sleep(long millis, int nanos) throws InterruptedException休眠当前线程 nanos 纳秒
public class demo11 {
    public static void main(String[] args) throws InterruptedException {
        System.out.println(System.currentTimeMillis());
        Thread.sleep(3 * 1000);//休眠三秒
        System.out.println(System.currentTimeMillis());
    }
}

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

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

相关文章

Unity 3D基础——缓动效果

1.在场景中新建两个 Cube 立方体&#xff0c;在 Scene 视图中将两个 Cude的位置错开。 2.新建 C# 脚本 MoveToTarget.cs&#xff08;写完记得保存&#xff09; using System.Collections; using System.Collections.Generic; using UnityEngine;public class MoveToTarget : M…

代理和多级代理

文章目录 代理使用场景代理过程实验演示多级代理 代理使用场景 1、拿下远程 web 服务器 2、webshell 链接不稳定&#xff0c;需要使用稳定的木马程序 3、远程服务器无法直接链接攻击者电脑 4、需要借助公网vps转发来自失陷服务器的木马流量 5、借助frp服务端(vps)和客户端(内网…

AI为锚,创新为帆,谱写数实融合发展新篇章

云聚园区&#xff0c;智享未来。9月27日&#xff0c;在苏州工业园区管理委员会、华为云计算技术有限公司的指导下&#xff0c;由SISPARK&#xff08;苏州国际科技园&#xff09;、华为&#xff08;苏州&#xff09;人工智能创新中心联合主办&#xff0c;东北大学工业智能与系统…

2.用Flask框架创建一个简单的Web程序

怎么安装Flask框架 在终端输入以下命令&#xff1a; pip install flask 验证flask安装&#xff1a; flask --version 编写app.py文件 app文件py如下&#xff1a; #导入flask框架中的两个模块 #Flask允许创建一个Flask应用实例&#xff0c;处理路由、请求和响应等功能 #render…

【交叉编译】tslib库交叉编译

tslib 是一个捕捉触屏事件的工具。qt 库在交叉编译的时候&#xff0c;提供了 -tslib 选项&#xff0c;使用该选项需要提前对 tslib 库进行交叉编译。 目录 1、源码下载 2、安装依赖 3、创建编译脚本 4、开始编译 1、源码下载 tslib 源码下载地址: https://github.com/lib…

oracle 与mysql兼容日期(格式:YYYY年MM月DD日)

日期类型&#xff1a;date 查询sql&#xff1a; select concat(concat(concat(to_char(END_DATE,YYYY),年),concat(to_char(END_DATE,MM),月)),concat(to_char(END_DATE,DD),日)) AS dateInfo from test显示结果&#xff1a;

python jieba 词性标注 中文词性分类 nlp jieba.posseg

参考&#xff1a;https://blog.csdn.net/yellow_python/article/details/83991967 from jieba.posseg import dt dt.word_tag_tab[好看] >>> vflag_en2cn { ‘a’: ‘形容词’, ‘ad’: ‘副形词’, ‘ag’: ‘形语素’, ‘an’: ‘名形词’, ‘b’: ‘区别词’, ‘…

2023年工业大麻行业研究报告

第一章 行业概况 1.1 定义 工业大麻行业是一个多面向且快速发展的领域&#xff0c;涵盖了从种植、加工到分销各个环节。与休闲大麻不同&#xff0c;工业大麻主要用于制造和商业用途。工业大麻的种植重点放在产生纤维、籽和生物质等有价值的产品上&#xff0c;而非产生高含量的…

Rt-Thread 移植3--临界段保护(KF32)

1.什么是临界段 执行下的时候不能被中断的代码段。 系统调度和外部中断都会打断&#xff0c;系统调度本质是产生PendSV中断。NMI FAULST和Hard FAULE除外2.代码实现 contex_gcc.c中添加 rt_base_t __attribute__((noinline)) rt_hw_interrupt_disable(void) {asm volatile(…

阿里云服务器内存型20个实例规格性能特点和适用场景汇总

阿里云服务器ECS内存型规格族属于独享型云服务器&#xff0c;在高负载不会出现计算资源争夺现象&#xff0c;因为每一个vCPU都对应一个Intel Xeon 处理器核心的超线程&#xff0c;内存型实例的云服务器其CPU处理器与内存配比通常为1:8&#xff0c;最高比约为1:20。本文介绍阿里…

Seata入门系列【6】分布式事务之TCC模式简介

1 历史背景 关于TCC的概念&#xff0c;最早是由Pat Helland于2007年发表的一篇名为《Life beyond Distributed Transactions:an Apostate’s Opinion》的论文提出。在该论文中&#xff0c;TCC还是以Tentative-Confirmation-Cancellation命名。正式以Try-Confirm-Cancel作为名称…

【运维笔记】swow源码编译安装

swow的github网址 https://github.com/swow/swow 从github中拉取源码 git pull https://github.com/swow/swow.git 编译安装 github中readme文件讲述了安装方法 这里整理了命令&#xff0c;进入拉取项目的目录后依次执行命令即可 #pwd 确保自己在swow目录中&#xff0c;如…

linux中搭建c语言环境并编译

安装gcc 安装 yum install gcc 检查 gcc --version 编译文件 1.编写test.c vim test.c #include <stdio.h>int main() {printf(" ***** \n");printf(" * o o * \n");printf("* ^ *\n");printf("* - *\n");printf…

VUE树结构实现

实现效果: 数据库表结构如下: 要求:需要有parentId,id。parentId就是父记录的id 表数据要求:一定不要让一条记录的parentid和id相同 前端代码: 注意:el-table标签里面需要加上属性,才可以有下拉箭头的样式 <el-table v-loading="listLoading" :data

· C语言在自动化如何控制系统

今日话题 C语言在自动化如何控制系统&#xff1f; 类&#xff1a;理解构造函数、属性、封装、继承、多态&#xff0c;有助于组织管理系统对象。 数据库&#xff1a;熟悉常见数据库&#xff08;如Access、SQL&#xff09;、SQL语言和操作&#xff0c;用于高效数据管理。 …

MySQL Row size too large (> 8126)

错误信息 ERROR 1118 (42000) at line 901: Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMATDYNAMIC or ROW_FORMATCOMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline. 错误原因 这个问题…

Stewart六自由度正解、逆解计算-C#和Matlab程序

目录 一、Stewart并联六自由度正解计算 &#xff08;一&#xff09;概况 &#xff08;二&#xff09;Matlab正解计算 1、参考程序一 2、参考程序二 &#xff08;三&#xff09;C#程序正解计算 1、工程下载链接 2、正解运行计算 &#xff08;四&#xff09;正程…

zabbix监控——自定义监控内容

目录 自定义监控项步骤 案例 1、明确需要执行的命令 2、创建 zabbix 的监控项配置文件&#xff0c;用于自定义 key&#xff0c;并重启zabbix-agent2 3、.在服务端验证新建的监控项 4、在 Web 页面创建自定义监控项模板 1&#xff09;创建模板 2&#xff09;创建监控项 …

振弦传感器和无线振弦采集仪在隧道安全监测的解决方案

振弦传感器和无线振弦采集仪在隧道安全监测的解决方案 隧道作为交通工程的重要组成部分&#xff0c;具有极高的安全风险&#xff0c;因此隧道安全监测是必不可少的。振弦传感器和无线振弦采集仪作为隧道安全监测的两种重要设备&#xff0c;能够有效地监测隧道的振动情况&#…

探索JSON能力,看这一篇就够了

KING BASE JSON&#xff08;JavaScript Object Notation&#xff09;作为一种流行的数据格式&#xff0c;相比于TEXT和LOB类型&#xff0c;能更高效地实现数据的访问。此外&#xff0c;JSON能打通关系型和非关系型数据存储之间的界限&#xff0c;为业务提供更好的架构选择。 Ki…