当前位置: 首页 > news >正文

【多线程】Thread类的用法

文章目录

    • 1. Thread类的创建
      • 1.1 自己创建类继承Thread类
      • 1.2 实现Runnable接口
      • 1.3 使用匿名内部类创建Thread子类对象
      • 1.4 使用匿名内部类创建Runnable子类对象
      • 1.5 使用lambda创建
    • 2. Thread常见的构造方法
      • 2.1 Thread()
      • 2.2 Thread(Runnable target)
      • 2.3 Thread(String name)
      • 2.4 Thread(Runnable target, String name)
    • 3. Thread常见的属性
    • 4. 线程的使用
      • 4.1 启动线程
      • 4.2 中断线程
      • 4.3 等待线程
      • 4.4 休眠线程

1. Thread类的创建

1.1 自己创建类继承Thread类

package Thread;//继承Thread类实现线程
class MyThread extends Thread{@Overridepublic void run() {System.out.println("hello run");}
}
public class Dome1 {public static void main(String[] args){//创建线程MyThread myThread = new MyThread();//启动线程myThread.start();}
}

1.2 实现Runnable接口

//使用Runnable的方式创建线程
class MyRunnable implements Runnable{@Overridepublic void run() {System.out.println("hello run");}
} 
public class Dome2 {public static void main(String[] args){//创建线程MyRunnable myRunnable = new MyRunnable();Thread t = new Thread(myRunnable);//启动t.start();}
}

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

//通过匿名内部类的方式创建线程
public class Dome3 {public static void main(String[] args) {//创建线程Thread t = new Thread(){@Overridepublic void run() {System.out.println("hello run");}};//启动线程t.start();}
}

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

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

1.5 使用lambda创建

//lambda实现线程
public class Dome5 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread( () -> {System.out.println("hello run");});t.start();}
}

2. Thread常见的构造方法

2.1 Thread()

//创建Thread对象
Thread t = new Thread();

2.2 Thread(Runnable target)

//使用Runnable对象创建线程对象
Thread t = new Thread(new Runnable);

2.3 Thread(String name)

//为这个线程命名
Thread t = new Thread("名字");

2.4 Thread(Runnable target, String name)

//使用Runnable对象创建线程对象并命名
Thraed t = new Thread(new Runnable,"名字");

3. Thread常见的属性

属性获取方法
IDgetId()
namegetName()
状态getState()
优先级getPriority()
是否为后台线程isDaemon()
是否存活isAlive()
是否中断isInterrupted()
public class Test4 {public static void main(String[] args) {Thread t = new Thread(() -> {//Thread.currentThread调用当前线程对象,相当于t,这个时候t还未初始化成功,不能直接使用System.out.println("ID: " + Thread.currentThread().getId());System.out.println("name: " + Thread.currentThread().getName());System.out.println("状态: " + Thread.currentThread().getState());System.out.println("优先级: " + Thread.currentThread().getPriority());System.out.println("是否为后台线程: "  + Thread.currentThread().isDaemon());System.out.println("是否存活: " + Thread.currentThread().isAlive());System.out.println("是否中断: " + Thread.currentThread().isInterrupted());});t.start();}
}

运行结果1

注意:

  1. ID 是线程的唯一标识,不同线程不会重复
  2. 名称是各种调试工具用到
  3. 状态表示线程当前所处的一个情况,下面我们会进一步说明
  4. 优先级高的线程理论上来说更容易被调度到
  5. 关于后台线程,需要记住一点:JVM会在一个进程的所有非后台线程结束后,才会结束运行。
  6. 是否存活,即简单的理解,为 run 方法是否运行结束了

4. 线程的使用

4.1 启动线程

前面我们已经知道了线程的创建,构造等方法,但这些其实都是准备工作,还没有真正的从底层创建出一个线程,只有调用start方法够才算真正的创建成功线程。
//直接调用就可以 t.start()

4.2 中断线程

当线程启动的时候,有时里面是循环,这时线程便不会停止,我们便要想办法中断线程。中断线程有个简单的方法直接使用Thread.stop()方法,但是,这种方法是unsafe,而且基本上已经deprecated。
所以我们调用interrupt()方法进行停止线程,但它并不会直接停止线程,而是对线程内进行标记,标记为Boolean类的true。这个时候我们再调用下面两个方法。
public static boolean interruputed();测试线程是否为中断状态,还执行后会标记清除为false。
public boolean isInterputed();测试线程是否为中断状态,但不清除标记。

添加标志符进行中断:

//中断线程,添加标志位
public class Test3 {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {//while(!Thread.currentThread().isInterrupted()){System.out.println(Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {
//                   e.printStackTrace();break;}}});//启动线程t1.start();//休眠3秒Thread.sleep(3000);t1.interrupt();}
}

注意:
如果休眠中中断线程,则会异常,反之,也是。

//中断线程,添加标志位
public class Test3 {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {
//           while(!Thread.currentThread().isInterrupted()){try {Thread.sleep(100000);} catch (InterruptedException e) {e.printStackTrace();System.out.println("异常!");}
//           }System.out.println("end!");});t1.start();Thread.sleep(3000);t1.interrupt();System.out.println(t1.isInterrupted());System.out.println(Thread.interrupted());}
}

在这里插入图片描述

4.3 等待线程

方法说明
join()等待线程结束
join(long millis)等待线程结束,最多等待millis毫秒
join(long millis,int nanos)和2相比更加的精确

当我们同时启动几个线程,由于线程启动时随机无序的,我们无法得知谁先结束,这个时候就可以使用join方法让线程等待。

例如:当我们想让张三先上班,等张三上班结束,李四接班,那么我们就可以写出下面代码。

public class Test5 {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {while (!Thread.currentThread().isInterrupted()){System.out.println(Thread.currentThread().getName() + "在上班");try {Thread.sleep(1000);} catch (InterruptedException e ){break;}}},"张三");Thread t2 = new Thread(() -> {while(!Thread.currentThread().isInterrupted()){System.out.println(Thread.currentThread().getName() + "在上班");try {Thread.sleep(1000);} catch (InterruptedException e) {break;}}},"李四");System.out.println("监督张三");t1.start();Thread.sleep(3000);t1.interrupt();t1.join();System.out.println("监督李四");t2.start();Thread.sleep(3000);t2.interrupt();t2.join();}
}

4.4 休眠线程

线程在执行的时候是非常快的,这个时候我们就可以让线程执行一次后就休眠一定时间,便于更好的观察。
上面代码中我们也多次用到。

Thread.sleep(long millis),里面millis单位是毫秒。

相关文章:

【多线程】Thread类的用法

文章目录 1. Thread类的创建1.1 自己创建类继承Thread类1.2 实现Runnable接口1.3 使用匿名内部类创建Thread子类对象1.4 使用匿名内部类创建Runnable子类对象1.5 使用lambda创建 2. Thread常见的构造方法2.1 Thread()2.2 Thread(Runnable target)2.3 Thread(String name)2.4 Th…...

第八章 贪心算法 part03 1005.K次取反后最大化的数组和 134. 加油站 135. 分发糖果 (day34补)

本文章代码以c为例! 一、力扣第1005题:K 次取反后最大化的数组和 题目: 给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组: 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。 重复这个过程恰好 k 次。可以多次选择…...

Android Activity启动过程一:从Intent到Activity创建

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。 目录 一、概览二、应用内启动源码流程 (startActivity)2.1 startActivit…...

第9章:聚类

聚类任务 性能度量 距离度量 非度量距离 原型聚类 有很好的统计学上的意义,但是只能找到椭球形的聚类。 密度聚类 层次聚类...

程序员为什么要写bug,不能一次性写好吗?

仅仅听到“Bug”这个词就会让你作为一个开发人员感到畏缩。我们相信,优秀的程序员是那些编写无错误代码的人。随着一些开发人员强调要成为一名零错误程序员,我们进行了更深刻的思考,并发现事实的准确性。 所有制作的软件都应该没有错误。对此…...

Nginx反向代理其他服务

Nginx反向代理 嘿,你的网络遇到了限制,不能直接通过服务的端口进行访问?别担心,我们可以借助Nginx这个超级英雄来解决这个问题!让我给你讲讲关于Nginx反向代理的故事吧。 首先,让我们明确一下反向代理的概…...

MQ 简介-RabbitMQ

一. MQ 简介 消息队列作为高并发系统的核心组件之一,能够帮助业务系统结构提升开发效率和系统 稳定性,消息队列主要具有以下特点: 削峰填谷:主要解决瞬时写压力大于应用服务能力导致消息丢失、系统奔溃等问题系统解耦:解决不同重要程度、不…...

强化学习(2)

强化学习(1) 1.多智能体深度强化学习重要性采样 多智能体深度强化学习(Multi-Agent Deep Reinforcement Learning,MADRL)是指在多智能体环境下使用深度强化学习算法进行协同学习。重要性采样(Importance Sampling)是…...

Visual Studio 2022的MFC框架——theApp全局对象

我是荔园微风,作为一名在IT界整整25年的老兵,今天我们来重新审视一下Visual Studio 2022下开发工具的MFC框架知识。 MFC中的WinMain函数是如何与MFC程序中的各个类组织在一起的呢?MFC程序中的类是如何与WinMain函数关联起来的呢&#xff1f…...

SpringBoot Cache

一、基本概念 Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。 Spring Cache 提供了一层抽象,底层可以切换不同的缓存实现,例如: • EHCache • Caffeine …...

vue 简单实验 自定义组件 component

1.代码 <script src"https://unpkg.com/vuenext" rel"external nofollow" ></script> <div id"components-demo"><button-counter></button-counter> </div> <script> // 创建一个Vue 应用 const ap…...

C++ 改善程序的具体做法 学习笔记

1、尽量用const enum inline替换#define 因为#define是做预处理操作&#xff0c;编译器从未看见该常量&#xff0c;编译器刚开始编译&#xff0c;它就被预处理器移走了&#xff0c;而#define的本质就是做替换&#xff0c;它可能从来未进入记号表 解决方法是用常量替换宏 语言…...

Unity 之 GameObject.Find()在场景中查找指定名称的游戏对象

文章目录 GameObject.Find 是 Unity 中的一个函数&#xff0c;用于在场景中查找指定名称的游戏对象。这个函数的主要作用是根据游戏对象的名称来查找并返回一个引用&#xff0c;使您能够在代码中操作该对象。以下是有关 GameObject.Find 的详细介绍&#xff1a; 函数签名&…...

flink on yarn with kerberos 边缘提交

flink on yarn 带kerberos 远程提交 实现 flink kerberos 配置 先使用ugi进行一次认证正常提交 import com.google.common.io.Files; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.apache.flink.client.cli.CliFrontend; import o…...

NodeJS的简介以及下载和安装

本章节会带大家下载并安装NodeJs 以及简单的入门&#xff0c;配有超详细的图片&#xff0c;一步步带大家进行下载与安装 NodeJs简介关于前端与后端Node是什么&#xff1f;为什么要学习NodeNodeJS的优点&#xff1a; NodeJS的下载与安装NodeJS的下载&#xff1a; NodeJS的快速入…...

量化面试-概率题

文章目录 一、题目1.糖果罐&#xff08;绿皮书79页&#xff09;2 折木棍&#xff08;绿皮书89页&#xff09;3 第一张ACE&#xff08;绿皮书95页&#xff09;4 n个均匀分布之和&#xff08;绿皮书95页&#xff09; 二、答案1. 糖果罐2 折木棍3 第一张ACE4 n个均匀分布之和 一、…...

【spark】java类在spark中的传递,scala object在spark中的传递

记录一个比较典型的问题&#xff0c;先讲一下背景&#xff0c;有这么一个用java写的类 public class JavaClass0 implements Serializable {private static String name;public static JavaClass0 getName(String str) {if (name null) {namestr;}return name;}... }然后在sp…...

php 文字生成图片保存到本地

你可以使用PHP的GD库来生成图片并保存到本地。首先&#xff0c;你需要确保你的PHP环境已经安装了GD库。然后&#xff0c;你可以使用GD库的函数来创建一个画布&#xff0c;并在上面绘制文字。最后&#xff0c;使用imagepng或imagejpeg函数将画布保存为PNG或JPEG格式的图片文件。…...

面试手撕—二叉搜索树及其后序遍历

一、引言 在面试地平线的时候&#xff0c;聊到了二叉搜索树&#xff0c;让手撕二叉搜索树&#xff0c;以下是要求 1、用类模板实现二叉搜索树 2、写一个函数&#xff0c;实现给一个vector数组&#xff0c;转换成二叉搜索树 3、写出二叉搜索树的后序遍历 二、代码实现 #inc…...

Java数据结构面试题以及答案

本专栏记录Java后端开发相关的面试题&#xff0c;欢迎大家阅读专栏的其他文章。 目录 1.B树和B树的区别&#xff1f;B树和B树的优点分别是&#xff1f; 2.排序算法的种类和复杂度 3.HashMap和Hashtable的原理、区别、应用场景 4.ConcurrentHashMap的原理、应用场景 5.Arra…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample&#xff08;样本数&#xff09; 表示测试中发送的请求数量&#xff0c;即测试执行了多少次请求。 单位&#xff0c;以个或者次数表示。 示例&#xff1a;…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景

Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知&#xff0c;帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量&#xff0c;能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度&#xff0c;还为机器人、医疗设备和制造业的智…...

面试高频问题

文章目录 &#x1f680; 消息队列核心技术揭秘&#xff1a;从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"&#xff1f;性能背后的秘密1.1 顺序写入与零拷贝&#xff1a;性能的双引擎1.2 分区并行&#xff1a;数据的"八车道高速公路"1.3 页缓存与批量处理…...

内窥镜检查中基于提示的息肉分割|文献速递-深度学习医疗AI最新文献

Title 题目 Prompt-based polyp segmentation during endoscopy 内窥镜检查中基于提示的息肉分割 01 文献速递介绍 以下是对这段英文内容的中文翻译&#xff1a; ### 胃肠道癌症的发病率呈上升趋势&#xff0c;且有年轻化倾向&#xff08;Bray等人&#xff0c;2018&#x…...

C++11 constexpr和字面类型:从入门到精通

文章目录 引言一、constexpr的基本概念与使用1.1 constexpr的定义与作用1.2 constexpr变量1.3 constexpr函数1.4 constexpr在类构造函数中的应用1.5 constexpr的优势 二、字面类型的基本概念与使用2.1 字面类型的定义与作用2.2 字面类型的应用场景2.2.1 常量定义2.2.2 模板参数…...

Ray框架:分布式AI训练与调参实践

Ray框架&#xff1a;分布式AI训练与调参实践 系统化学习人工智能网站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目录 Ray框架&#xff1a;分布式AI训练与调参实践摘要引言框架架构解析1. 核心组件设计2. 关键技术实现2.1 动态资源调度2.2 …...

新版NANO下载烧录过程

一、序言 搭建 Jetson 系列产品烧录系统的环境需要在电脑主机上安装 Ubuntu 系统。此处使用 18.04 LTS。 二、环境搭建 1、安装库 $ sudo apt-get install qemu-user-static$ sudo apt-get install python 搭建环境的过程需要这个应用库来将某些 NVIDIA 软件组件安装到 Je…...