【Java系列】详解多线程(一)

个人主页:兜里有颗棉花糖
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创
收录于专栏【Java系列专栏】
本专栏旨在分享学习Java的一点学习心得,欢迎大家在评论区交流讨论💌

目录

  • 一、背景引入
  • 二、线程的引入
    • 小总结
  • 三、进程和线程的关系(面试题)
  • 四、第一个多线程程序
    • 每个线程都能够被独立的进行调用执行

一、背景引入

在引入多线程之前,我们先来看一下进程是为了干什么的,一句话总结就是:满足"并发编程"这样的需求。

早些时候,CPU都是单核心的CPU,但是随着技术工艺变得越来越强,单核心CPU的性能的确是越来越强的,但是单核心CPU技术工艺研发到一定程度后就会遇到瓶颈,从而导致单核心CPU的研发变得非常缓慢。于是就就逐渐向多核心CPU的方向进行发展研究。

好了,既然CPU逐渐变成了多核心,那么应用程序也应该做出相应的调整来把多核心的CPU给利用起来(意思就是仅仅由硬件上的支撑是不够的,我们还要由软件上的配合),以免造成一核有难,多核围观的场景

另外,早期的系统一般是单任务系统,即在同一时刻只能使用一个程序,而无法在同一时刻内使用多个程序,完成多个任务。而要完成多个任务的话,进程就显得特别关键。

二、线程的引入

多进程能够很好的实现并发编程的效果,但还由一个缺点就是进程太重,即消耗资源更多,速度更慢。如果进程的创建和销毁比较少的话那还勉强可以,但是如果进程的创建和销毁非常频繁的话,此时就会产生非常多的开销。开销大主要体现在需要给进程分配资源,而给进程分配资源的这一过程也是需要很多时间成本的。

于是就有人提出这样一个解决方案:即在创建进程的过程中,只分配简单的PCB(进程控制块),而不去分配后续需要的内存硬盘资源,即把分配资源的时间省去,这样既可以完成多并发编程的任务又能够提升进程创建销毁的速度。

这样一种只分配简单的PCB而不去分配后续需要的内存硬盘资源的这样一种方式称为轻量级进程,也叫做线程(thread)。所以简单来说线程就是只分配PCB,但不分配后续需要的内存硬盘资源

但是线程总归是要完成任务的,如果不去分配后续需要的内存硬盘资源显然是不可以的,于是就有人想出来这样的一个办法:在创建进程的时候,先把后续需要的内存资源分配好;后续创建线程的时候让线程在进程内部直接复用先前进程分配创建好的内存资源(线程和进程直接的关系:进程包含线程)

另外,一个进程至少要包含一个线程,最初进程创建出来的时候,我们可以将这个进程视为一个只包含一个线程的进程(注意此时创建进程的过程是需要分配资源的,同时第一个线程的创建开销是可能是比较大的),我们后续再次创建线程的时候就不需要分配资源了,也就省去了分配资源的过程,因为资源已经是有了的。

小总结

好了,我们已经知道多进程已经可以完成并发编程的任务了,但是由于进程本身有些重,重就体现在进程的创建和销毁所需要的内存硬盘资源开销有些大。

所以就引入了线程(也称为轻量级进程)来更高的解决上述的问题。进程中的多个线程公共复用了进程中的各种内存硬盘等资源,同时这些进程可以各自独立的在CPU中进行调度。所以这样的话线程既可以完成并发编程的效果,又可以以轻量级的方式来完成各种任务。

另外,这里补充一个点,进程和线程是两个不同的概念,在Linux中复用了PCB这个结构体来描述线程,而在Windows中,描述进程和线程是不同的结构体。所以在Windows中,为了更好的描述进程,有时一个PCB对应一个线程,多个PCB对应一个进程(即可能是多一个PCB来描述一个进程,一个PCB来描述一个线程)。

CPU的内存指针和文件描述符表文件描述符表这两个字段内容在同一个进程是一样的,但是上下文信息、状态、优先级、记账信息......等支持调度的属性,这些PCB就不一样了(意思就是每个线程独立去CPU上进行调度,每个线程的上下文、状态、优先级、记账信息等支持调度的属性都有自已独立的一份)。

线程的引入的确能够提高任务执行的速度,同时随着线程数量的增多任务执行完成的速度当然也会增快,但是线程的数量不能是无限制提高的(CPU的核心数的数量是有限的。),同时线程数量也不是越多越好,因为线程调度的开销有时会拖慢整个程序的效率。

两句话总结:

1.进程是操作系统中进行资源分配的基本单位。
2.线程是操作系统中进程调度执行的基本单位。

三、进程和线程的关系(面试题)

1.进程包含线程,都是实现并发编程的一种方式,但是由于多进程的创建和销毁的效率并没有那么高,且线程比进程更加轻量。所以就引入了多线程的概念。

2.进程是系统分派资源的基本单位;线程是是系统调度的基本单位,创建进程的时候已经把分配资源(这里的资源主要指的是虚拟地址空间和符表)的工作做了,后续创建进程的时候直接复用之前的资源即可。

3.每个进程都有自己独立的地址空间,彼此直接不会相会影响到,从而保证了每个进程的独立性,保证了数据稳定性。
需要注意的是,如果多个组线程程共用了一份地址空间的话,一旦某个线程抛出异常的话,就可能会导致一整个进程结束(所以多个线程之间是很容易相互影响的。 )。

四、第一个多线程程序

线程本身是操作系统的概念,而操作系统又提供了API来供我们使用线程,来完成多线程编程(在Linux中称为pthread库,通过这个库我们就可以完成多线程编程)。

而在Java中,把操作系统中的API进程分装,即提供了Thread类来帮助哦我们来完成多线程编程。

Java标准库中的Thread类来自于java.lang这个包,而Java.lang这个包不需要我们手动的import

好了,光说不练是不行的,接下来我们就来看一下我们的第一个线程程序,请看下图:

package thread;

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("Hello,world!");
    }
}

public class Demo01 {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
    }
}

现在我们来解释上述的线程程序,上述代码的MyThread类中的run()方法是重写的Thread父类中的run()方法,这个run()方法相当于线程程序的入口,线程程序跑起来之后具体要干什么事情,都是通过这个run()方法来进行描述的。

myThread.start()这个操作就是在创建一个线程(即在底层调用操作系统提供的创建线程的API,同时在操作系统内核中创建出其对应的PCB结构,并将其加入到链表中)。此时这个新创建出来的线程就会参与到cpu的调度中,接下来线程要执行的任务,就是run()方法中的内容。

接下来我如果注释掉myThread.start();,即直接执行MyThread类中的run()方法,请看下图:
在这里插入图片描述
我们来解释上述程序,我们前面已经知道,start方法会去调用操作系统提供的创建线程的API,同时在操作系统内核中创建出其所对应的PCB,此时这个新创建出来的线程就会参与cpu调度
而我们直接运行run方法的话,此时并没有调用操作系统提供的创建线程的API,也就没有创建出新的进程。
当整个程序开始运行的时候,此时会先创建出来一个java进程,这个java进程中至少包含一个进程,称为主进程,这个主进程是负责执行main()方法的线程。每一个线程都能够被独立的进行调用和执行。

每个线程都能够被独立的进行调用执行

每个线程都能够被独立的进行调用执行,现在我们来写一个程序来体现这句话。请看:

在这里插入图片描述
运行结果如下(由于程序是一个死循环,所以这里只是截取了部分的程序运行结果),如下图:
在这里插入图片描述
我们可以看到程序一会执行Hello,Linux!一会执行Hello,world!
解释:start()是新线程执行的入口,而主线程和新线程是并发执行的一个关系。先新创建出来的线程创建出来之后会执行run()方法中的代码,而main()方法则是继续往后执行。所以最终呈现出来的程序运行效果就是一会执行Hello,Linux!,一会执行Hello,world!

现在我们在来看一段程序,请看下图:
在这里插入图片描述
我们可以看到上述代码把myThread.start()注释掉了,相当于我们并没有创建线程,那么此时的话只有整个程序只有主线程这一个线程了。
分析到这里我们已经知道整个程序只有线程(也就是主线程),那么执行的run()方法就是在主线程中去执行的,因为整个程序就只有一个线程(即主线程)。

总结一下:

  • 每个线程都是一个独立的执行流。
  • 每个线程都可以执行一段代码。
  • 每个线程之间是并发的关系。

好了,本文到这里就结束了,就到这里吧,再见啦友友们!!!在这里插入图片描述

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

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

相关文章

echarts绘制一个饼图

其他echarts&#xff1a; qecharts绘制一个柱状图&#xff0c;柱状折线图 效果图&#xff1a; 代码&#xff1a; <template><div class"wrapper"><div ref"pieChart1" id"pieChart1"></div><div ref"pieCha…

CCF编程能力等级认证GESP—C++1级—20230611

CCF编程能力等级认证GESP—C1级—20230611 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09;判断题&#xff08;每题 2 分&#xff0c;共 20 分&#xff09;编程题 (每题 25 分&#xff0c;共 50 分)时间规划累计相加 答案及解析单选题判断题编程题1编程题2 单选题…

docker安装配置prometheus+node_export+grafana

简介 Prometheus是一套开源的监控预警时间序列数据库的组合&#xff0c;Prometheus本身不具备收集监控数据功能&#xff0c;通过获取不同的export收集的数据&#xff0c;存储到时序数据库中。Grafana是一个跨平台的开源的分析和可视化工具&#xff0c;将采集过来的数据实现可视…

2023年6月21日 Go生态洞察:Go 1.21版发行候选版的深入分析

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

基于SpringBoot+Thymeleaf+Mybatis实现大学生创新创业管理系统(源码+数据库+项目运行指导文档)

一、项目简介 本项目是一套基于SpringBoot实现大学生创新创业管理系统&#xff0c;主要针对计算机相关专业的正在做bishe的学生和需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目可以直接作为bishe使用。 项目都经过严格调试&#…

局域网共享打印机设置,解决709、11B等一切共享问题

Win7、Win10、Win11添加共享打印机经常出现局域网共享打印机出错&#xff0c;常规的添加方式是SMB共享&#xff0c;一更新就出问题&#xff0c;报错0x00000709、0x0000011b等。 网上有许多方法&#xff0c;如卸载更新补丁&#xff0c;替换“win32spl.dll”文件&#xff0c;修改…

排查200M宽带下行速度低于100M问题(七十七)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

sql注入 [GXYCTF2019]BabySQli1

打开题目 多次尝试以后我们发现存在一个admin的账号&#xff0c;但是密码我们不知道 我们尝试一下万能密码 admin or 11 -- q 报错 我们尝试bp抓一下包看看 看着很像编码 先去base32解码 再base64解码 得到 我们从这个sql语句中得到注入点为name 根据报错信息我们知道是…

Python语言基础知识(一)

文章目录 1、Python内置对象介绍2、标识符与变量3、数据类型—数字4、数据类型—字符串与字节串5、数据类型—列表、元组、字典、集合6、运算符和表达式7、运算符和表达式—算术运算符8、运算符和表达式—关系运算符9.1、运算符和表达式— 成员测试运算符in9.2、运算符和表达式…

vue+echarts实现桑吉图的效果

前言&#xff1a; 在我们项目使用图形的情况下&#xff0c;桑吉图算是冷门的图形了&#xff0c;但是它可以实现我们对多级数据之间数据流向更好的展示的需求&#xff0c;比如&#xff0c;我们实际数据流向中&#xff0c;具有1对多&#xff0c;多对多的情况下&#xff0c;如果用…

uni-app实现安卓原生态调用身份证阅读器读卡库读身份证和社保卡、银行卡、IC卡等功能

DONSEE系列多功能读写器Android Uniapp API接口规范V1.0.0 本项目Uniapp调用了身份证读卡器的库文件&#xff1a;DonseeDeviceLib-debug.aar&#xff0c;该库放到nativeplugins\donsee-card\android&#xff0c;然后会自动加载。SDK会自动检查是否拥有USB设备权限&#xff0c;…

关于物联网仪表ADW300 远传电表的详细介绍-安科瑞 蒋静

1概述 ADW300无线计量仪表主要用于计量低压网络的三相有功电能&#xff0c;具有体积小、精度高、功能丰富等优点&#xff0c;并且可选通讯方式多&#xff0c;可支持 RS485 通讯和 Lora、NB、4G、wifi 等无线通讯方式&#xff0c;增加了外置互感器的电流采样模式&#xff0c;从而…

数据结构与算法(五)回溯算法(Java)

目录 一、简介1.1 定义1.2 特性1.3 结点知识补充1.4 剪枝函数1.5 使用场景1.6 解空间1.7 实现模板 二、经典示例2.1 0-1 背包问题2.2 N皇后问题 一、简介 1.1 定义 回溯法&#xff08;back tracking&#xff09;是一种选优搜索法&#xff0c;又称为试探法&#xff0c;按选优条…

为什么 AWS 数据库不讲 HTAP

在 AWS re:Invent 2023 掌门人 Adam Selipsky 的 Keynote 上&#xff0c;数据库方面最重磅的主题是 Zero-ETL&#xff0c;从 TP 数据库 (RDS, Aurora, DynamoDB) 同步数据到 AP 数据库 (Redshift)。 Zero-ETL 是 AWS 在去年 re:invent 2022 上推出的概念&#xff0c;今年则继…

网络层之IP组播

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

【力扣】206.反转链表

206.反转链表 这道题有两种解法&#xff0c;但不只有两种&#xff0c;嘿嘿。 法一&#xff1a;迭代法 就是按循序遍历将每一个指针的指向都给改了。比如说1——>2——>3改为null<——1<——2<——3这样。那这里以第二个结点为例&#xff0c;想一想。我想要指向…

如何在Linux上部署1Panel运维管理面板并远程访问内网Web端管理界面

文章目录 前言1. Linux 安装1Panel2. 安装cpolar内网穿透3. 配置1Panel公网访问地址4. 公网远程访问1Panel管理界面5. 固定1Panel公网地址 前言 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器&#xff0c;包括主机监控、…

BPM、ERP、OA 各自的功能和特点是什么?怎么配合使用?

OA、BPM、ERP几乎是任何一家企业都会接触到的信息管理系统及程序。 首先&#xff0c;我从定义上理清BPM、ERP和OA ERP(Enterprise Resource Planning,企业资源计划)&#xff0c;一般围绕供应链、生产制造和财务为核心。 BPM&#xff08;business process management&#xf…

智能优化算法应用:基于野马算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于野马算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于野马算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.野马算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

如何使用Net2FTP轻松部署本地Web文件管理器并远程访问管理内网资源?

文章目录 1.前言2. Net2FTP网站搭建2.1. Net2FTP下载和安装2.2. Net2FTP网页测试 3. cpolar内网穿透3.1.Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 文件传输可以说是互联网最主要的应用之一&#xff0c;特别是智能设备的大面积使用&#xff0c;无论是个人…