【JAVAEE】多线程

【JAVAEE】多线程

  • 一、进程
      • 1.1 进程的定义
      • 1.2 进程和线程的联系
  • 二、线程
      • 2.1 JConsole工具
      • 2.2 创建线程
        • 2.2.1 Thread类,start(),run()
        • 2.2.2 继承Thread类
        • 2.2.3 实现Runnable接口
        • 2.2.4 匿名内部类
        • 2.2.5 使用Runnable接口的匿名内部类
        • 2.2.6 使用lambda表达式
      • 2.3 Thread类及常用方法
        • 2.3.1 Thread类的构造方法
        • 2.3.2 Thread类的常见属性
      • 2.4 线程状态
      • 2.5 后台线程和前台线程
      • 2.6 休眠线程
      • 2.7 线程等待
      • 2.8 终止线程
        • 2.8.1 自定义标志位终止线程
        • 2.8.2 使用自带标志位终止线程

博客结尾包含此篇博客的全部代码!!!

一、进程

1.1 进程的定义

  • 进程(Process)是计算机操作系统中的一个核心概念,它是程序在计算机上的一次动态执行实例。换句话说,进程是程序运行时的活动表现形式。它包含了程序代码、数据、运行状态以及系统资源的分配情况。进程相当于一个正在运行的程序
  • 进程也是系统分配资源的基本单位

在这里插入图片描述

1.2 进程和线程的联系

首先,并发编程成为我们的需求!每个客户端给服务器发送请求,服务器就需要给客户端提供服务。在90年代,多进程是一种解决方案!!!

那么既然有解决方法,为什么还要引入线程?
线程:线程是轻量级的进程!!!

线程相比于进程:

  • 创建线程比创建进程更快。
  • 销毁线程比销毁进程更快。
  • 调度线程比调度进程更快。

举个例子:

假设这个任务是“消灭”桌子上的两只鸡,在一个房间中有一个桌子,桌子上放了两只鸡。
进程的解决方法:再创建一个房间,将这两只鸡分开,分别“消灭”。
在这里插入图片描述
线程的解决方法:在这个房间中“消灭”这两只鸡。
在这里插入图片描述
这两个对比你发现:相同的人数,进程需要再创建一个房间(开销很大),而线程则啥都不需要添加。

二、线程

2.1 JConsole工具

在创建线程之前,先给大家介绍一下JConsole 工具, JConsole是JDK 自带的一款图形化监控和管理工具,基于 JMX(Java Management Extensions)技术实现。它能够连接到本地或远程的 Java 虚拟机(JVM),并实时监控和管理 Java 应用程序的性能和资源使用情况。
这里我们就用它来监控我们的线程!
JConsole:找到我们的JDK安装的安装路径,像我这里安装的JDK17–>bin–>jconsole.exe
在这里插入图片描述
如何使用?
测试代码:代码运行起来才能观察到,如果线程结束就观察不到。

class MyThread extends Thread {@Overridepublic void run() {while (true) {System.out.println(" hello Thread");}}
}public class Demo1 {public static void main(String[] args) {MyThread t1 = new MyThread();t1.start();}
}

在这里插入图片描述

在这里插入图片描述
刚进去出现不安全连接,由于是我是自己练习,所以点不安全连接。
在这里插入图片描述

2.2 创建线程

2.2.1 Thread类,start(),run()
  • Thread类:线程,是操作系统的概念,操作系统定义了一些api(应用程序编程接口)来供程序员使用,而java中将这些api封装成Thread类来供使用!Thread类在java.long这个包中,所以用的时候不需要导包。
  • start():用于启动一个新线程,线程调度器会调用 run() 方法。start() 方法只能被调用一次。如果尝试多次调用 start(),会抛出 IllegalThreadStateException 异常。
  • run():定义线程的执行逻辑,但不会启动新线程。如果需要启动新线程,必须通过 start() 方法。相当于线程的入口。
2.2.2 继承Thread类

代码:

class MyThread extends Thread {@Overridepublic void run() {while (true) {System.out.println(" hello Thread");}}
}public class Demo1 {public static void main(String[] args) {MyThread t1 = new MyThread();t1.start();while(true) {System.out.println(" hello main");}}
}
2.2.3 实现Runnable接口

实现Runnable接口的MyRunnnable类,将new MyRunnable()当作一个对象传给Thread的构造函数。
代码:

class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("Hello Thread");}
}public class Demo2 {public static void main(String[] args) {Thread t1 = new Thread(new MyRunnable());t1.start();}
}
2.2.4 匿名内部类
public class Demo3 {public static void main(String[] args) {Thread thread = new Thread(){@Overridepublic void run() {System.out.println("Hello Thread");}};thread.start();System.out.println("Hello main");}
}
2.2.5 使用Runnable接口的匿名内部类
public class Demo4 {public static void main(String[] args) {Thread t1 = new Thread(new Runnable(){@Overridepublic void run() {System.out.println("Hello Thread");}});t1.start();}
}
2.2.6 使用lambda表达式
public class Demo5 {public static void main(String[] args) {Thread thread = new Thread(()->{while(true){System.out.println("Hello Thread");}});thread.start();while(true){System.out.println("Hello main");}}
}

2.3 Thread类及常用方法

2.3.1 Thread类的构造方法

在这里插入图片描述
解释一下第四个Thread(Runnable target,String name)!


public class Demo6 {public static void main(String[] args) {Thread thread = new Thread(new Runnable() {@Overridepublic void run() {while (true) {System.out.println("Hello Thread");}}}, "Thread1");thread.start();while (true) {System.out.println("Hello main");}}
}

在这里插入图片描述

在这里插入图片描述

2.3.2 Thread类的常见属性

在这里插入图片描述
• ID 是线程的唯⼀标识,不同线程不会重复
• 获取线程的名称
• 获取线程的当前状态,如新建、就绪、运行、阻塞、等待、终止等
• 优先级⾼的线程理论上来说更容易被调度到
• 关于后台线程,需要记住⼀点:JVM会在⼀个进程的所有⾮后台线程结束后,才会结束运⾏。
• 是否存活,即简单的理解,为 run ⽅法是否运⾏结束了
• 判断线程是否被中断。线程的中断状态可以通过调用 interrupt() 方法来设置,该方法会改变线程的中断状态,但不会停止线程的执行

2.4 线程状态

public class Demo7 {public static void main(String[] args) {for(Thread.State state: Thread.State.values()) {System.out.println(state);}}
}

获取线程的所有状态:
在这里插入图片描述
• NEW:

  • 当线程对象被创建,但尚未调用 start() 方法时,线程处于新建状态。
  • 在这个状态下,线程尚未开始执行。
public class Demo7 {public static void main(String[] args) {Thread thread=new Thread(()->{System.out.println("Hello Thread");});System.out.println(thread.getState());thread.start();}
}

• RUNNABLE:

  • 当调用线程的 start() 方法后,线程进入就绪状态。
  • 在这个状态下,线程已经准备好运行,等待 CPU 时间片以便执行。
  • 就绪状态的线程可能正在 JVM 中运行,也可能正在等待操作系统调度。
public class Demo7 {public static void main(String[] args) throws InterruptedException {Thread thread=new Thread(()->{for(int i=0;i<3;i++) {System.out.println("Hello Thread");}});System.out.println(thread.getState());thread.start();System.out.println(thread.getState());}
}

• BLOCKED: 由锁导致的,后面会出一篇关于线程安全问题,到时候会详细介绍,这里就不过多介绍了

  • 当线程等待获取一个排他锁,如同步块或同步方法中的锁时,线程进入阻塞状态。
  • 线程在等待锁释放后才能继续执行。
  • 阻塞状态的线程不会被分配 CPU 时间片。

• WAITING:
时间阻塞(这个等待是没时间上限的)

  • 当线程执行 wait()、join() 或 LockSupport.park() 方法后,线程进入等待状态。
  • 在这个状态下,线程需要等待其他线程执行特定的操作(如通知或中断)才能继续。
  • 等待状态的线程不会被分配 CPU 时间片。
public class Demo7 {public static void main(String[] args) throws InterruptedException {Thread thread=new Thread(()->{while(true) {}});System.out.println(thread.getState());thread.start();thread.join();}
}

在这里插入图片描述
发现main线程是waiting。

• TIMED_WAITING:
时间阻塞(这个等待是有时间上限的),不参与CPU调度

public class Demo7 {public static void main(String[] args) throws InterruptedException {Thread thread=new Thread(()->{while(true) {try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});System.out.println(thread.getState());thread.start();Thread.sleep(1000);System.out.println(thread.getState());}
}

• TERMINATED:

  • 当线程的 run() 方法执行完毕,或者线程被 stop() 方法(已废弃)强制停止,或者线程抛出未捕获的异常导致运行结束时,线程进入终止状态。
  • 在这个状态下,线程已经结束执行,不再消耗任何资源。
public class Demo7 {public static void main(String[] args) throws InterruptedException {Thread thread=new Thread(()->{for(int i=0;i<3;i++) {System.out.println("Hello Thread");}});System.out.println(thread.getState());thread.start();Thread.sleep(6000);System.out.println(thread.getState());}
}

2.5 后台线程和前台线程

前台线程:一般我们创建的线程都是前台线程,只要前台线程不结束,JVM就不会退出。
后台线程:也称守护线程,后台线程一般都是辅助性的任务,如果前台线程全部结束,即使还有后台线程在运行,JAM也会退出。

public class Demo8 {public static void main(String[] args) {Thread thread1=new Thread(()->{for(int i=0;i<2;i++){System.out.println("Hello Thread");}});thread1.start();System.out.println(thread1.isDaemon());//false 说明他不是守护线程Thread thread2=new Thread(()->{for(int i=0;i<2;i++){System.out.println("Hello Thread");}});thread2.setDaemon(true);thread2.start();System.out.println(thread2.isDaemon());//true}
}

2.6 休眠线程

在这里插入图片描述
下面那个可以达到纳秒级别,这种适用于军工,航天等之类,一把情况下用不到。
在这里插入图片描述
这里还有一个需要注意的是:由于 Runnable 接口的 run 方法没有 throws 子句,所以这里只能用try-catch 来捕获异常。

2.7 线程等待

在这里插入图片描述

public class Demo10 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(()->{for (int i = 0; i < 3; i++){System.out.println("Hello Thread");}});thread.start();thread.join();System.out.println("Hello main");}
}

先执行thread线程,thread线程执行完,再执行main线程。为了防止死等,也可以设置等待时间。

2.8 终止线程

让run方法尽快结束。

2.8.1 自定义标志位终止线程
public class Demo11 {public static  boolean flag=true;public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(()->{while(flag){System.out.println("Hello Thread");}System.out.println("Bye Bye Thread");});thread.start();Thread.sleep(1000);flag=false;}
}

将flag设置为全局变量,这里就是匿名内部类访问外部类,而不是变量捕获。
为什么不可以将flag设置为局部变量?
在这里插入图片描述

很有可能是main线程已经执行完,已经将flag销毁了,但是Thread线程中还没执行到while(flag)…

2.8.2 使用自带标志位终止线程

在这里插入图片描述
Java自带标志位来结束终止线程。先使用Thread.currentThread()来获取当前线程,在.isInterrupted()获取标志位。然后再主进程中调用interrupte()方法来将标志位值修改为true。

public class Demo12 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (!Thread.currentThread().interrupted()) {System.out.println("Hello Thread");}System.out.println("Bye Bye Thread");});thread.start();Thread.sleep(1000);thread.interrupt();}
}

调用interrupte()方法,不仅会设置标志位,还会提前唤起sleep阻塞

public class Demo12 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() ->{while (!Thread.currentThread().isInterrupted()) {System.out.println("hahah");try {Thread.sleep(1000);} catch (InterruptedException e) {//1.不操作继续执行线程(因为sleep唤醒后会又将标志位改为true)e.printStackTrace();//2.结束线程break;//3.进行其它操作}}});thread.start();Thread.sleep(1000);thread.interrupt();}
}

此篇博客的全部代码!!!

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

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

相关文章

手机打电话时如何识别对方按下的DTMF按键的字符-安卓AI电话机器人

手机打电话时如何识别对方按下的DTMF按键的字符 --安卓AI电话机器人 一、前言 前面的篇章中&#xff0c;使用蓝牙电话拦截手机通话的声音&#xff0c;并对数据加工&#xff0c;这个功能出来也有一段时间了。前段时间有试用的用户咨询说&#xff1a;有没有办法在手机上&#xff…

【Go】十八、http 调用服务的编写

http接口框架的搭建 这个http接口框架的搭建参考之前的全量搭建&#xff0c;这里是快速搭建的模式&#xff1a; 直接对已有的http模块进行复制修改&#xff0c;主要修改点在于 proto部分与api、router 部分&#xff0c;剩余的要针对进行修改模块名称。 接口的具体编写 在 a…

WiseFlow本地搭建实录---保姆教程

今天从零开始搭建了Wiseflow的本地环境搭建&#xff0c;目前使用的都是免费的API&#xff0c;我建议大家可以一起尝试一下搭建自己的关键信息的数据库&#xff0c;我是windows的环境&#xff0c;但是其他的应该也差不多&#xff0c;踩了很多坑&#xff0c;希望这篇文章能帮大家…

数的计算(蓝桥云课)

题目描述 输入一个自然数 n (n≤1000)n (n≤1000)&#xff0c;我们对此自然数按照如下方法进行处理: 不作任何处理; 在它的左边加上一个自然数,但该自然数不能超过原数的一半; 加上数后,继续按此规则进行处理,直到不能再加自然数为止。 问总共可以产生多少个数。 输入描述 输…

知识库功能测试难点

图表交互功能测试难点 知识库图表类型多&#xff0c;每种图表交互功能不同。像柱状图&#xff0c;可能有点击柱子查看详细数据、鼠标悬停显示数据提示等交互&#xff1b;折线图除了这些&#xff0c;还可能支持缩放查看不同时间段数据。多种交互操作在不同图表间存在差异&#x…

【人工智能】数据挖掘与应用题库(201-300)

1、在LetNet5网络中,卷积核的大小是? 答案:5*5 2、LeNet5网络参数的数量约为? 答案:6万 3、AlexNet与LeNet5相比,使用了哪些机制来改进模型的训练过程? 答案: 数据增广Dropout抑制过拟合ReLU激活函数CUDA加速神经网络训练4、VGGNet使用的卷积核的大小是? 答案:…

web安全渗透测试 APP安全渗透漏洞测试详情

前言 小小白承包了一块20亩的土地&#xff0c;依山傍水&#xff0c;风水不错。听朋友说去年玉米大卖&#xff0c;他也想尝尝甜头&#xff0c;也就种上了玉米。 看着玉米茁壮成长&#xff0c;别提小小白心里多开心&#xff0c;心里盘算着玉米大买后&#xff0c;吃香喝辣的富贵…

CSS处理内容溢出

<!DOCTYPE html> <html lang"zh-cn"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>处理内容溢出</title><style>#d1{wid…

拉丁超立方采样(Latin Hypercube Sampling)技术详解及实现

拉丁超立方采样(Latin Hypercube Sampling)技术详解 拉丁超立方采样(Latin Hypercube Sampling)技术详解1. 引言2. 拉丁超立方采样原理3. 数学公式描述4. Python代码实现代码解析5. 应用场景与优势6. 在化工中的应用6.1 工艺参数优化6.2 不确定性量化与风险评估6.3 实验设计…

docker-compose部署onlyoffice8.3.0并支持ssl,且支持通过nginx代理,关闭JWT配置

编写docker-compose文件 mkdir -p /data/onlyoffice && echo "version: 3services:onlyoffice:container_name: OnlyOfficeimage: onlyoffice/documentserver:8.3.0restart: alwaysports:- 8088:80- 64431:443environment:TZ: Asia/ShanghaiJWT_ENABLED: falsevol…

Sliding Window Attention(滑动窗口注意力)解析: Pytorch实现并结合全局注意力(Global Attention )

Sliding Window Attention&#xff08;滑动窗口注意力&#xff09;解析 Sliding Window Attention&#xff08;滑动窗口注意力&#xff09; 是 Longformer (来源&#xff1a;https://arxiv.org/pdf/2004.05150)提出的 稀疏注意力机制&#xff0c;旨在解决 标准 Transformer 计算…

【运维】内网服务器借助通过某台可上外网的服务器实现公网访问

背景&#xff1a; 内网服务器无法连接公网,但是办公电脑可以连接内网服务器又可以连接公网。 安装软件 1、frp 2、ccproxy 配置 1、内网服务器 # 内网服务器启动frp服务配置文件参考vi frps.ini# frps.ini [common] bind_port 7000# 备注: bind_port端口可以随意配置。配置完…

flask 是如何分发请求的?

这篇博客会涉及一些 WSGI 的知识&#xff0c;不了解的可以看这篇博客&#xff0c;简单了解一下。 Python 的 WSGI 简单入门 一、请求在 flask 中的处理过程 我们先来看一下 werkzeug.routing 包下 Map 和 Rule 方法的使用&#xff0c;这里给出一个官方的示例&#xff08;我进…

怎么获取免费的 GPU 资源完成大语言模型(LLM)实验

怎么获取免费的 GPU 资源完成大语言模型(LLM)实验 目录 怎么获取免费的 GPU 资源完成大语言模型(LLM)实验在线平台类Google ColabKaggle NotebooksHugging Face Spaces百度飞桨 AI Studio在线平台类 Google Colab 特点:由 Google 提供的基于云端的 Jupyter 笔记本环境,提…

Python开发Django面试题及参考答案

目录 Django 的请求生命周期是怎样的? Django 的 MTV 架构中的各个组件分别是什么? Django 的 URL 路由是如何工作的? Django 的视图函数和视图类有什么区别? Django 的模板系统是如何渲染 HTML 的? Django 的 ORM 是如何工作的? Django 的中间件是什么?它的作用是…

【图像的读写与基本操作】

图像的读写与基本操作 目录 图像的读写与基本操作目标知识点1. 图像的读写 &#xff1a;2. 图像的缩放 &#xff1a;3. 图像的翻转 &#xff1a;4. 图像的裁剪 &#xff1a;5. 颜色空间转换 &#xff1a; 示例代码1. 图像的读写 &#xff1a;2. 图像的缩放 &#xff1a;3. 图像…

《数字图像处理》笔记

文章目录 第一章 绪论1.1 什么是数字图像处理数字图像的概念数字图像的组成数字图像处理的概念 1.4 数字图像处理的基本步骤 第二章 数字图像基础2.2 光和电磁波谱可见光单色光灰度级发光强度光通量亮度 2.3 图像感知和获取将照射能量变换为数字图像的传感器简单的图像形成模型…

网络安全扫描--基础篇

前言 1、了解互联网安全领域中日趋重要的扫描技术 2、了解在不同网络场景下扫描技术手段 3、熟悉linux下系统内核防护策略并能大件一个有效的系统防护体系 4、增强工作安全意识&#xff0c;并能有效的实践于工作场景中 目录 1、熟悉主机扫描工具&#xff08;fping&#xff0c;…

前端防重复请求终极方案:从Loading地狱到精准拦截的架构升级

&#x1f525; 事故现场还原&#xff1a;疯狂点击引发的血案 凌晨1点23分&#xff0c;监控系统突然告警&#xff1a; &#x1f4c9; 服务器CPU飙升至98% &#x1f5c3;️ 数据库出现3000脏数据 &#x1f4a5; 用户端弹出上百个错误弹窗 事故原因&#xff1a;黑产脚本通过0.5秒…

基于Spring Boot的供应商管理系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…