【Java EE】多线程(一)

在这里插入图片描述

📚博客主页:爱敲代码的小杨.

✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》

❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️

🙏小杨水平有限,欢迎各位大佬指点,相互学习进步!

文章目录

  • 1. 进程和多线程的概念
    • 1.1 进程
    • 1.2 线程
  • 2. 并发和并行
    • 2.1 并发
    • 2.2 并行
  • 3. 多线程的实现方式
    • 3.1继承 Thread 类
    • 3.2 实现 Runnale 接口
    • 3.3 其他形式

1. 进程和多线程的概念

1.1 进程

提到多线程就不得不提及“进程”这个概念。
进程:进程是操作系统结构的基础;是一次程序的执行;是一个程序及其数据在处理机上顺序执行时发生的活动;在程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。
举例:
image.png
我们可以将一个正在操作系统中运行的.exe程序理解成进程,进程是受操作系统管理的基本运行单元.

1.2 线程

线程:线程就可以理解成是在进程中独立的子任务。
多线程:多线程指的就是一个 .exe 程序同时执行多个子任务
image.png

举例:
运行QQ.exe时就有很多子任务在同时运行。比如:好友视频线程、下载文件线程、传输数据线程、发送表情线程等等,这些不同任务或者功能都可以同时运行,其中每一项任务完全可以理解成理“线程”在工作,传文件,发送图片表情等能有对应的线程在后台默默运行。

多线程的优点:使用多任务操作系统 Windows 后,可以最大限度地利用 CPU 的空闲时间处理其他的任务,比如一边让操作系统处理正在由打印机打印的数据,一般使用 Word 编辑文档。而 CPU 在这些任务之间不停地切换,由于切换的速度非常快,给使用者的感受就是这些任务似乎在同时运行。所以使用多线程技术后,可以在同一时间运行更多不同种类的任务。

小结:

  1. 有了多线程,我们就可以让程序同时做多件事情
  2. 多线程的作用:提高效率
  3. 多线程的应用场景:只要你想让多个事情同时运行就需要多线程,比如:软件中的消耗操作、所有的聊天软件、所有的服务器。

2. 并发和并行

2.1 并发

并发:在同一个时刻,有多个指令在单个 CPU 上交替执行

举例:我在打游戏的时候。又想喝可乐,于是我的右手一会拿鼠标,一会拿可乐,那么此时由于我的手速非常的快,在鼠标和可乐之间来回交替执行,此时我们就可以看作是并发,这里右手就是当做 CPU,鼠标和可乐就当做线程1和线程2,CPU 就是在这两条线程之间进行交替执行

红色的线比做 CPU ,蓝色的线比做 线程。
PixPin_2024-03-31_15-35-15.gif

2.2 并行

并行:在同时一个时刻,有多个指令在多个 CPU 上同时执行
image.png
红色的线比做 CPU ,蓝色的线比做 线程。
image.png
有人会疑问了我们的电脑上不是只有一个 CPU?为啥上图有两个 CPU 呢?
但是我们的电脑的 CPU 可以分为:2核4线程、4核8线程、8核16线程、16核32线程、32核64线程等等。这里线程的数量就是电脑能同时运行的线程。

这里我们用2核心4线程举例:
它可以同时运行4条线程,所以如果你的电脑当中只有4条线程,那么它就可以不用切换的,但是如果线程越来越多,那么这4条红线就会在多个线程之间随机的进行切换,所以在计算机中并发和并行有可能同时都在发生的

3. 多线程的实现方式

3.1继承 Thread 类

步骤:

  1. 定义类继承 Thread
  2. 重写 run方法
  3. 创建实例
  4. 启动线程

代码:

// 1.继承 Thread类
class MyThread extends Thread{
    // 2. 重写 run方法
    @Override
    public void run() {
        // 线程代码
        while (true) {
            System.out.println("hello thread");
            // sleep方法:休眠
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

public class Test {
    public static void main(String[] args) {
        // 3. 创建实例
        MyThread t = new MyThread();
        // 4.启动线程 
        t.start();

        while (true) {
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

运行结果:
recording.gif
【注意】:多线程是异步的,所以千万把 idea 里代码的顺序当成线程执行的顺序,线程被调用的时机是随机的。

3.2 实现 Runnale 接口

步骤:

  1. 实现 Runnale 接口
  2. 重写 run 方法
  3. 创建实例,调用 Thread 的构造方法时将 Runnable 对象作为 target 参数
  4. 启动线程

代码:

// 1. 实现Runnable 接口
class MyRunnable implements Runnable {
    // 重写 run 方法
    @Override
    public void run() {
        while (true) {
            System.out.println("hello Thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

public class Test3 {
    public static void main(String[] args) {
        // 3. 创建实例,调用 Thread 的构造方法时将 Runnable 对象作为 target 参数
        Thread t = new Thread(new MyRunnable());
        // 4. 启动线程
        t.start();

        while (true) {
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

运行结果
recording.gif

3.3 其他形式

  • 匿名内部类创建 Thread 子类对象

​ 代码:

public class Test4 {
    public static void main(String[] args) {
        new Thread(){
            @Override
            public void run() {
                while (true) {
                    System.out.println("hello Thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }.start();

        while (true) {
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

​ 运行结果:
recording.gif

  • 匿名内部类创建 Runable 子类对象

​ 代码:

public class Test5 {
    public static void main(String[] args) {
        new Thread(new MyRunnable()) {
            @Override
            public void run() {
                while (true) {
                    System.out.println("hello Thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }.start();

        while (true) {
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

​ 运行结果:
recording.gif

  • lambda 表达式创建 Runnable 子类对象

​ 代码:

public class Test6 {
    public static void main(String[] args) {
        Thread t =  new Thread(() -> {
            while (true) {
                System.out.println("hello Thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();

        while (true) {
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

​ 运行结果:
recording.gif

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

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

相关文章

Python爬虫验证码识别——手机验证码的自动化处理

手机验证码的自动化处理 有一种验证码就是手机验证码,如果在PC上出现了一个手机验证码,需要先在PC上输入手机号,然后把短信验证码发到手机上,再在PC上输入收到的验证码,才能通过验证。 遇到这样的情况,如…

【Linux在程序运行时打印调用栈信息(函数名,文件行号等)】

在程序运行时打印相关调用栈信息&#xff08;函数名&#xff0c;文件行号等&#xff09;,便于梳理调用逻辑等 //stack.c #include <stdio.h> #include <execinfo.h> #include <stdlib.h> #include <string.h> #include <stdbool.h>#define MAX_…

vue cesium heatmap 热力图

实现效果 引入 heatmap index.html 中引入 heatmap <script src"./heatmap.min.js"></script>使用 <script lang"ts" setup> import * as Cesium from cesium import cesium/Build/Cesium/Widgets/widgets.cssdefineOptions({ name: …

MySQL count函数的使用

count&#xff08;&#xff09;函数在使用时参数好像不能设置为表达式&#xff0c;只能设置成指定字段或* 比如在查询性别为男的成员数目时不能写&#xff1a; select count(gendermale) from user_profile ; 否则直接得到6&#xff0c;也就是等价于select count(gender) fro…

Docker镜像的(Dive)分析和(Grype)漏洞扫描

Dive dive能够分析docker镜像分层内容以及发现缩小docker/OCI镜像大小的方法。 提高部署效率&#xff1a;能够秒级快速启动一个应用&#xff0c;而传统的方式分钟级别以上&#xff1b; 提高运行效率&#xff1a;相对物理机和虚拟化&#xff0c;容器具有更高的资源利用率&…

【经典算法】LeetCode 21:合并两个有序链表Java/C/Python3实现含注释说明,Easy)

合并两个有序链表 题目描述思路及实现方式一&#xff1a;迭代&#xff08;推荐&#xff09;思路代码实现Java版本C语言版本Python3版本 复杂度分析 方式二&#xff1a;递归&#xff08;不推荐&#xff09;思路代码实现Java版本C语言版本Python3版本 复杂度分析 总结相似题目 标…

LLM大语言模型(八):ChatGLM3-6B使用的tokenizer模型BAAI/bge-large-zh-v1.5

背景 BGE embedding系列模型是由智源研究院研发的中文版文本表示模型。 可将任意文本映射为低维稠密向量&#xff0c;以用于检索、分类、聚类或语义匹配等任务&#xff0c;并可支持为大模型调用外部知识。 BAAI/BGE embedding系列模型 模型列表 ModelLanguageDescriptionq…

《QT实用小工具·五》串口助手

1、概述 源码放在文章末尾 该项目实现了串口助手的功能&#xff0c;可在界面上通过串口配置和网络配置进行串口调试。 基本功能 支持16进制数据发送与接收。支持windows下COM9以上的串口通信。实时显示收发数据字节大小以及串口状态。支持任意qt版本&#xff0c;亲测4.7.0 到…

[leetcode] 100. 相同的树

给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 示例 1&#xff1a; 输入&#xff1a;p [1,2,3], q [1,2,3] 输出&#xff1a;true示例 2&a…

微信小程序【从入门到精通】——服务器的数据交互

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

【设计】6种ID生成策略描述,优点 ,缺点 ,适用场景

1.数据库自增ID 描述 自增Id是在设计表时将id字段的值设置为自增的形式&#xff0c;这样当插入一行数据时无 需指定id会自动根据前一字段的Id值1进行填充 优点 主键自动增长&#xff0c;不用手工设值、数字型&#xff0c;占用空间小、检索非常有利、有顺序&#xff0c;不会…

08、JS实现:数组两数之和算法的两种解决方案(一步一步剖析,很详细)

数组两数之和的算法 Ⅰ、数组两数之和算法的方案一&#xff1a;1、题目描述&#xff1a;2、解题思路&#xff1a;3、实现代码&#xff1a; Ⅱ、数组两数之和算法的方案二&#xff1a;1、实现代码&#xff1a; Ⅲ、小结&#xff1a; Ⅰ、数组两数之和算法的方案一&#xff1a; …

51单片机学习笔记11 使用DS18B20温度传感器

51单片机学习笔记11 使用DS18B20温度传感器 一、DS18B20简介1. 主要特点2. 工作原理3. 引脚说明4. ROM 二、1-wire协议简介1. 总线结构&#xff1a;2. 通信方式&#xff1a;3. 数据传输&#xff1a;4. 设备识别&#xff1a;5. 供电方式&#xff1a;6. 应用场景&#xff1a;7. 优…

vue页面实现旋转饼图

一、示例图片 二、参考 3D饼图-半透明 - ECharts图表集,echarts gallery社区,Make A Pie,分享你的可视化作品isqqw.com 三、实现 1、自定义组件RotatingPieChart.vue <template><div>【旋转饼图】</div><div ref"chart" class"chart-c…

C语言单链表的窗口化操作

#include <stdio.h> #include <stdlib.h>// 定义链表的节点结构 struct Node {int data;struct Node* next; };// 初始化链表 void initialize(struct Node** head) {*head NULL; }// 在链表末尾插入节点 void insert(struct Node** head, int value) {// 创建新节…

基于BEV的自动驾驶会颠覆现有的自动驾驶架构吗

基于BEV的自动驾驶会颠覆现有的自动驾驶架构吗 引言 很多人都有这样的疑问–基于BEV(Birds Eye View)的自动驾驶方案是什么&#xff1f;这个问题&#xff0c;目前学术界还没有统一的定义&#xff0c;但从我的开发经验上&#xff0c;尝试做一个解释&#xff1a;以鸟瞰视角为基础…

Web框架开发-Form组件和ajax实现注册

一、注册相关的知识点 1、Form组件 我们一般写Form的时候都是把它写在views视图里面,那么他和我们的视图函数也不影响,我们可以吧它单另拿出来,在应用下面建一个forms.py的文件来存放 2、局部钩子函数 1 2 3 4 5 6 7 # 局部钩子函数 def clean_username(self): userna…

《QT实用小工具·六》代码行数统计工具

1、概述 源码放在文章末尾 该项目实现了对不同编程语言文件的代码行数的统计 统计的内容包含&#xff1a; 1、代码行数 2、注释行数 3、空白行数 下面是demo演示&#xff1a; 项目部分代码如下所示&#xff1a; #pragma execution_character_set("utf-8")#inclu…

区块链食品溯源案例实现(一)

引言&#xff1a; 食品安全问题一直是社会关注的热点&#xff0c;而食品溯源作为解决食品安全问题的重要手段&#xff0c;其重要性不言而喻。传统的食品溯源系统往往存在数据易被篡改、信息不透明等问题&#xff0c;而区块链技术的引入&#xff0c;为食品溯源带来了革命性的变革…

【ProComponents】解决 ProTable 中 params 参数改变,request 函数未触发问题

文章目录 先建议自查下官方文档&#xff0c;了解params和request直接的关系 确定params绑定的参数是否改变&#xff0c;例如 user_name 参数 import { ProTable, WxIcon } from /components; import { getSearchParams } from ice; import { useEffect, useMemo, useRef, useS…