【Java EE】多线程(一)

news2024/11/28 22:36:28

在这里插入图片描述

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

✨专栏:《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

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

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

相关文章

物联网实战--入门篇之(六)嵌入式-WIFI驱动(ESP8266)

目录 一、WIFI简介 二、基础网络知识 三、思路讲解 四、代码分析 4.1 状态机制 4.2 客户端连接 4.3 应用数据接收处理 4.4 数据发送 4.5 主函数调用 4.6 网络连接ID分配 五、总结 一、WIFI简介 WIFI在我们生活中太常见了,手机电脑都可以用WiFi连接路由器进行上…

MIT最新研究成果 机器人能够从错误中纠偏 无需编程介入和重复演示

目前科学家们正在努力让机器人变得更加智能,教会他们完成诸如擦拭桌面,端盘子等复杂技能。以往机器人要在非结构化环境执行这样的任务,需要依靠固定编程进行,缺乏场景通用性,而现在机器人的学习过程主要在于模仿&#…

开关恒流源简介

目录 工作原理 设计要点 应用场景 初步想法,为参加活动先占贴(带家人出去玩没时间搞~~),后面优化 开关恒流源是一种基于开关电源技术的恒流输出电源设备。它采用开关管进行高速的开关动作,通过控制开关管的导通和截…

linux 一些命令

文章目录 linux 一些命令fdisk 磁盘分区parted 分区文件系统mkfs 格式化文件系统fsck 修复文件系统 mount 挂载swap 交换分区清除linux缓存df du 命令raid 命令基本原理硬raid 和 软raid案例raid 10 故障修复,重启与卸载 lvm逻辑卷技术LVM的使用方式LVM 常见名词解析…

数据库---------完全备份和增量备份的数据恢复,以及断点恢复

目录 一、在数据库表中,分三次录入学生考试成绩 1.1先创建库,创建表,完成三次数据的录入 1.2首次录入成绩后,做该表的完全备份 1.3第二次插入后 做增量备份 1.4第三次插入后 做增量备份 二、模拟数据丢失,并使用…

大文件上传做断点续传(有详细的代码内容)

文章目录 一、是什么分片上传断点续传 二、实现思路三、使用场景小结参考文献 一、是什么 不管怎样简单的需求,在量级达到一定层次时,都会变得异常复杂 文件上传简单,文件变大就复杂 上传大文件时,以下几个变量会影响我们的用户…

标题:Vue3 中父组件向子组件通信的方式

标题:Vue3 中父组件向子组件通信的方式 在 Vue3 中,父组件和子组件之间可以通过一些方式进行通信。其中,父组件向子组件通信主要有两种方式:传值和调用子组件的方法。 一、父组件向子组件传值 当父组件需要向子组件传递数据时&a…

快速排序---算法

1、算法概念 快速排序:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的数据均比另一部分的数据小,则可分别对这两部分记录继续进行排序,以达到震哥哥序列有序。 快速排序的最坏运行情况是O(),比如说顺序数…

设计一个动物声音“模拟器”,希望模拟器可以模拟许多动物的叫声。

设计一个动物声音“模拟器”,希望模拟器可以模拟许多动物的叫声。要求如下: (1)编写接口Animal Animal接口有2个抽象方法cry()和getAnimaName(),即要求实现该接口的各种具体动物类给出自己的叫声和种类名称。 &…

设计模式 - 中介器模式

中介者模式使得组件通过一个中心点——中介者进行交互。组件不需要直接进行通信,而是将请求发送给中介者,由中介者进行转发!在JavaScript中,中介者往往只是一个对象字面量或一个函数。 你可以将这种模式与空中交通管制员和飞行员…

科技革新,OTG充电新纪元!

在科技日新月异的今天,数据交互已经渗透到我们生活的每个角落,无论是工作还是娱乐,它都发挥着不可替代的作用。OTG技术的出现,极大地简化了设备间的联接与数据交换过程,但随之而来的接口有限和续航问题,也让…

产品经理的进阶之路

点击下载《产品经理的进阶之路》 1. 前言 本文深入剖析了产品经理这一职业从产品专员起步,逐步晋升为产品经理、高级产品经理,直至产品总监的整个职业发展路径。在每个阶段,产品经理都需承担不同的工作职责,展现出独特的职业特点。 2. 产品专员 关键词【产品需求/原型/文…

计算机服务器中了rmallox勒索病毒怎么办?rmallox勒索病毒解密数据恢复

网络技术的不断发展与应用,大大提高了企业的生产运营效率,越来越多的企业开始网络开展各项工作业务,网络在为人们提供便利的同时,也会存在潜在威胁。近日,云天数据恢复中心接到多家企业的求助,企业的计算机…

设计模式-概述篇

1. 掌握设计模式的层次 第1层:刚开始学编程不久,听说过什么是设计模式第2层:有很长时间的编程经验,自己写了很多代码,其中用到了设计模式,但是自己却不知道第3层:学习过了设计模式,…

Vue 3.0生命周期:深入理解与用法

Vue 3.0生命周期:深入理解与用法 摘要: 本文将深入探讨Vue 3.0的生命周期,解释每个生命周期钩子的含义和用法,以及它们在开发过程中的重要性。我们将详细解析每个钩子的工作原理,并提供一些示例和最佳实践&#xff0c…

python爬取B站视频

参考:https://cloud.tencent.com/developer/article/1768680 参考的代码有点问题,请求头需要修改,上代码: import requests import re # 正则表达式 import pprint import json from moviepy.editor import AudioFileClip, Vid…

常见贪心问题详解

目录 贪心算法应用条件 常见贪心问题 活动安排问题(区间调度问题) 区间覆盖问题 最优装载问题1 最优装载问题2 多机调度问题 例题:翻硬币 例题:快乐司机 例题:防御力 例题:答疑 贪心算法应用条件…

【通信原理笔记】【三】模拟信号调制——3.1 模拟信号调制基本模型与思路

文章目录 前言一、模拟信号二、模拟调制系统模型三、模拟调制的三种方式四、调制的评价指标总结 前言 一般常见的信号的频带均集中在基带附近,如果要通过无线地方式传输,其较长的波长需要大型的天线才能传输,难以实现。另一方面基带的带宽资…

ruoyi-nbcio-plus基于vue3的flowable执行监听器的升级修改

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 http://122.227.135.243:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a…

Linux基础命令篇之——压缩与解压(tar、gzip、bzip2、zip和unzip)

linux基础命令——解压与压缩 以下是关于Linux命令tar、gzip、bzip2、zip和unzip的详细介绍: 1. tar 这个是Linux用的最多的解压缩命令 tar是Linux系统中用于创建和处理归档文件的命令。归档文件是一个包含多个文件和/或目录的单一文件。常与压缩命令gzip或bzip2结…