Java【多线程】(1)进程与线程


目录

1.前言

2.正文

2.1什么是进程

2.2PCB(进程控制块)

2.2.1进程id

2.2.2内存指针

2.2.3文件描述符表

2.2.4进程状态

2.2.4.1就绪状态

2.2.4.2阻塞状态

2.2.5进程优先级

2.2.6进程上下文

2.2.7进程的记账信息

2.3CPU操作进程的方法

2.4什么是线程

2.4.1进程与线程

2.4.2线程资源分布

2.5简单实现线程

2.5.1Thread类

2.5.2Runnable接口

2.5.2区分start和run

2.5.3查看线程

3.小结


1.前言

哈喽大家好吖,今天来给大家分享这一段时间刚上手的Java多线程的学习,多线程在以后实际项目开发中是一个十分核心的内容,需要认真学习并加以掌握,刚上手概念比较多,希望大家沉下心来慢慢学习,那么让我们开始这一部分的学习吧。

2.正文

在介绍线程之前,需要先讲解以下进程相关的概念,进程与线程之间息息相关,并且以后面试的时候会对这部分的原理内容进行考察。

2.1什么是进程

进程(Process) 是计算机中执行的程序的实例。它是操作系统分配资源和调度的基本单位。进程不仅包含程序代码本身,还包括程序执行时所需的资源和环境。每个进程都有独立的内存空间、寄存器、堆栈、程序计数器等,它们使进程能够在多任务操作系统中并发执行而不互相干扰。

如何在电脑上查看进程呢,其实很简单,打开任务管理器:

可以看到这里就标记着进程,当我们点到任务管理器详细信息一栏时,每一个进程的相关信息都会展示出来,这里先大概感知一下进程到底是什么。

2.2PCB(进程控制块)

操作系统通过管理进程来实现多任务操作,每个进程在操作系统中都有一个对应的进程控制块(PCB),用于存储进程的状态、程序计数器、寄存器等信息。当发生上下文切换时,操作系统会保存当前进程的状态,加载另一个进程的状态,从而实现进程间的切换。

下面是PCB的相关属性:


2.2.1进程id

PCB中的进程ID(Process ID,PID) 是操作系统用来唯一标识进程的一个标识符。每个进程在操作系统中都有一个独一无二的PID,它用于区分不同的进程并在进程管理中进行调度、监控和资源分配。

特点:

  • 唯一性
    每个进程都有一个唯一的PID,操作系统保证同一时刻不会有两个进程拥有相同的PID。

  • 生命周期
    当一个进程创建时,操作系统为其分配一个PID;当进程终止时,PID被释放,操作系统可以将其分配给新的进程。


2.2.2内存指针

内存指针(Memory Pointer)是一个重要的字段,用于保存与进程相关的内存管理信息。这个指针帮助操作系统追踪进程使用的内存区域,包括代码、数据、堆栈等。

内存指针都指向什么,都有什么作用呢:

  • 如果这个指针存储进程执行的代码,那么会使CPU能够正确地加载和执行指令。
  • 如果这个指针指向数据段,那么会使操作系统在运行时管理数据的访问。

2.2.3文件描述符表

文件描述符表是一个非常重要的字段,它用来管理进程与操作系统中文件的关系。文件描述符表存储着进程打开的文件的相关信息,每个文件在操作系统中都有一个唯一的标识符——文件描述符。这些文件描述符用于指代进程当前使用的文件资源,并为操作系统提供对这些文件的管理和访问。

作用:

  • 文件描述符表用于将进程与打开的文件建立关联。当一个进程打开文件时,操作系统会为该文件分配一个文件描述符,并将其存储在进程的文件描述符表中。这个描述符使进程能够通过标识符访问文件,而不需要知道文件的具体位置或物理存储,类似于一个特殊的指针

  • 文件描述符表中的每个条目对应一个打开的文件,操作系统可以根据文件描述符来执行文件的读写、关闭、定位等操作。


2.2.4进程状态

PCB中同样存储着当前进程的状态,下面那是俩个常见重要的进程状态。

2.2.4.1就绪状态

进程已经准备好运行,但由于CPU正在执行其他进程,因此处于等待中。操作系统将进程放入就绪队列,等待调度器选择该进程进行执行。此时进程的所有资源(除了CPU)都已分配好。

2.2.4.2阻塞状态

进程由于某些原因无法继续执行,此时进程不再占用CPU,而是处于阻塞状态。阻塞状态的进程会被移出CPU,直到它等待的条件满足时才会变为就绪状态。


2.2.5进程优先级

进程的优先级是操作系统用来决定不同进程执行顺序的重要标准。它指示了一个进程相对于其他进程的重要性,系统会优先选择优先级高的进程进行执行。但其实在真正执行时,优先顺序并不是定量的谁一定先执行谁一定后执行,而是一种定型的。

同样,某个进程的优先级也可以在任务管理器进行设置,但不知道为什么博主截不了图,右键单机进程就会有这个选项啦。


2.2.6进程上下文

进程的上下文指的是操作系统在切换进程时需要保存和恢复的信息。每个进程在运行时都有自己的执行状态,这些状态决定了进程如何继续执行。操作系统通过上下文切换在不同进程之间进行切换时,保存并恢复这些信息。每次切换时必须保存和恢复这些信息,以确保每个进程能够从中断的地方继续执行。


2.2.7进程的记账信息

统计每个进程在CPU上执行了多久。如果该进程长时间没分配到CPU资源,就会给这个进程倾斜一些CPU资源。


2.3CPU操作进程的方法

现在的电脑的CPU一般都有四核,八核,十六核,但我们打开任务管理器发现有成百上千个进程,那么电脑是如何同时操作这么多进程呢。

答案就是CPU对进程的操作的模式时分时复用

分时复用:操作系统将CPU的时间分成若干个时间片,若一个进程的时间片用完了,操作系统会把CPU控制权交给下一个进程,保证多个进程交替执行。

现代CPU的执行模式:

并行执行:

多个核同时处理多个进程

并发执行:

单个核按照分时复用的原则处理多个进程

2.4什么是线程

线程是操作系统调度的最小单位,是进程(程序运行的实例)中的一个执行单元。一个进程可以包含一个或多个线程,线程共享进程的资源(如内存、文件句柄),但每个线程都有自己的独立执行路径、寄存器和栈空间。

当然我们没有办法直接看到线程,得通过一些工具才能查看。

2.4.1进程与线程

让我们区分以下进程和线程并分析以下他们之间的联系:

  • 进程是线程的容器:一个进程可以包含一个或多个线程。线程依赖进程的存在,无法独立于进程运行。
  • 线程是进程的组成部分:线程负责在进程的上下文中执行代码,一个进程至少有一个主线程,用于启动和管理程序的运行。
  • 进程的生命周期包含线程的生命周期:当一个进程终止时,其所有线程也会终止。线程的存在和生命周期完全依附于所在进程。

2.4.2线程资源分布

类似于进程,线程也有其对应的属性:

线程是进程中的执行单元,多个线程共享进程的资源,如内存空间、文件描述符等

但每个线程也有独立的资源,包括栈、程序计数器和寄存器。操作系统通过合理的资源分配和调度机制,确保多线程程序高效、安全地执行。

2.5简单实现线程

创建线程主要有俩种方式,一种是继承Thread类,另一种是Runnable的接口,下文详解。

2.5.1Thread类

操作步骤:

  • 创建一个类并继承Thread类。
  • 重写Thread类的run()方法,将线程执行的具体任务写在run()方法中。
  • 创建线程对象并调用start()方法启动线程。
static class myThread extends Thread{
        @Override
        public void run() {
            System.out.println(("线程已执行"));
        }
    }

    public static void main(String[] args) {
        myThread myThread1 = new myThread();
        myThread1.run();
    }

 

2.5.2Runnable接口

操作步骤:

  • 创建一个类并实现Runnable接口。
  • 重写Runnable接口中的run()方法,将线程任务写在该方法中。
  • 创建一个Thread对象,将实现了Runnable接口的实例作为参数传递给Thread构造方法。
  • 调用Thread对象的start()方法启动线程。
static class myRunable implements Runnable{
        @Override
        public void run() {
            while(true){
                System.out.println("线程正在被执行");
            }
        }
    }

    public static void main(String[] args) {
        myRunable myRunable1 = new myRunable();
        Thread thread = new Thread(myRunable1);
        thread.start();

        while(true){
            System.out.println("主函数正在被执行");
        }
    }

我们可以发现此时俩个线程,一个是主函数的,另一个是新创立的,在交替执行。

2.5.2区分start和run

这里可能有细心的小伙伴们观察出来,第一个我们用了run方法,第二个我们用了start方法,那么这俩种方法有什么区别吗:

  • start()方法

    • 用于启动一个新的线程。
    • 它会调用线程的底层实现,告诉JVM创建一个新的线程。
    • 然后,新线程会自动调用run()方法中定义的逻辑。
    • start()使线程并发执行。
  • run()方法

    • 是线程要执行的任务逻辑。
    • 如果直接调用run()方法,并不会创建新线程,而是由当前线程执行它。
    • 相当于普通的同步方法调用。

2.5.3查看线程

想要查看线程的话我们需要去JDK中去寻找一个叫做jconsole的exe文件:

连接后就能查看线程了:

3.小结

今天的分享到这里就结束了,喜欢的小伙伴不要忘记点点赞点个关注,你的鼓励就是对我最大的支持,加油!

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

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

相关文章

一个专为云原生环境设计的高性能分布式文件系统

大家好,今天给大家分享一款开源创新的分布式 POSIX 文件系统JuiceFS,旨在解决海量云存储与各类应用平台(如大数据、机器学习、人工智能等)之间高效对接的问题。 项目介绍 JuiceFS 是一款面向云原生设计的高性能分布式文件系统&am…

Jmeter中的断言

7)断言 1--响应断言 功能特点 数据验证:验证响应数据是否包含或不包含特定的字符串、模式或值。多种匹配类型:支持多种匹配类型,如文本、正则表达式、文档等。灵活配置:可以设置多个断言条件,满足复杂的测…

游戏引擎学习第23天

实时代码编辑功能的回顾 当前实现的实时代码编辑功能已经取得了显著的成功,表现出强大的性能和即时反馈能力。该功能允许开发者在修改代码后几乎立即看到变化在运行中的程序中体现出来,极大提升了开发效率。尽管目前的演示内容较为简单,呈现…

排序算法之冒泡排序篇

冒泡排序的思想: 是一个把元素从小到大排的一个算法思想 相邻的两个元素两两比较,大的那一个元素向后移,小的那个元素向前移 核心逻辑: 比较所有相邻的两个项,如果第一个比第二个大,就交换它们 从头开始…

Java ArrayList 与顺序表:在编程海洋中把握数据结构的关键之锚

我的个人主页 我的专栏:Java-数据结构,希望能帮助到大家!!!点赞❤ 收藏❤ 前言:在 Java编程的广袤世界里,数据结构犹如精巧的建筑蓝图,决定着程序在数据处理与存储时的效率、灵活性以…

【笔记】自动驾驶预测与决策规划_Part8_数据驱动的规划方法

文章目录 0. 前言1.生成模型1.1 Diffusion-ES1. Diffusion-ES算法介绍2. Diffusion-ES算法具体流程Diffusion Model 是什么?Diffusion-ES: Evolutionary StrategiesDiffusion-ES MethodDiffusion-ES Mapping Language instructions to reward functions with LLM pr…

React中事件处理和合成事件:理解与使用

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Redis设计与实现第14章 -- 服务器 总结(命令执行器 serverCron函数 初始化)

14.1 命令请求的执行过程 一个命令请求从发送到获得回复的过程中,客户端和服务器都需要完成一系列操作。 14.1.1 发送命令请求 当用户在客户端中输入一个命令请求的时候,客户端会把这个命令请求转换为协议格式,然后通过连接到服务器的套接字…

【C语言】字符串左旋的三种解题方法详细分析

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 💯前言💯题目描述💯方法一:逐字符移动法💯方法二:使用辅助空间法💯方法三:三次反转法💯方法对…

【AI绘画】Midjourney进阶:色调详解(上)

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AI绘画 | Midjourney 文章目录 💯前言💯Midjourney中的色彩控制为什么要控制色彩?为什么要在Midjourney中控制色彩? 💯色调白色调淡色调明色调 &#x1f4af…

零基础学安全--云技术基础

目录 学习连接 前言 云技术历史 云服务 公有云服务商 云分类 基础设施即服务(IaaS) 平台即服务(PaaS) 软件即服务(SaaS) 云架构 虚拟化 容器 云架构设计 组件选择 基础设施即代码 集成部署…

【Linux】网络通信

TCP协议是一个安全的、面向连接的、流式传输协议,所谓的面向连接就是三次握手,对于程序猿来说只需要在客户端调用connect()函数,三次握手就自动进行了。先通过下图看一下TCP协议的格式,然后再介绍三次握手的具体流程。 TCP的三次握…

Pgsql:json字段查询与更新

1.查询json字段的值 SELECT attribute_data->>设施类别 mycol, * FROM gis_coord_data WHERE attribute_data->>设施类别阀门井 查询结果如下: 2.更新json字段中的某个属性值 UPDATE gis_coord_data SET attribute_data(attribute_data::jsonb ||{&quo…

对于GC方面,在使用Elasticsearch时要注意什么?

大家好,我是锋哥。今天分享关于【对于GC方面,在使用Elasticsearch时要注意什么?】面试题。希望对大家有帮助; 对于GC方面,在使用Elasticsearch时要注意什么? 1000道 互联网大厂Java工程师 精选面试题-Java…

基于Netty实现聊天室

前言 了解了Netty的基本功能和相关概念,使用基于Netty实现多人聊天的功能。 需求 1.服务端能够接收客户端的注册,并且接受用户的信息注册 2.服务端能够处理客户端发送的消息,并且根据消息类型进行私发或者广播发送消 3.服务端能够私发消…

Linux -日志 | 线程池 | 线程安全 | 死锁

文章目录 1.日志1.1日志介绍1.2策略模式1.3实现日志类 2.线程池2.1线程池介绍2.2线程池的应用场景2.3线程池的设计2.4代码实现2.5修改为单例模式 3.线程安全和函数重入问题3.1线程安全和函数重入的概念3.2总结 4.死锁4.1什么是死锁4.2产生死锁的必要条件4.3避免死锁 1.日志 1.…

【博主推荐】C#的winfrom应用中datagridview常见问题及解决方案汇总

文章目录 1.datagridview绘制出现鼠标悬浮数据变空白2.datagridview在每列前动态添加序号2.1 加载数据集完成后绘制序号2.2 RowPostPaint事件绘制 3.datagridview改变行样式4.datagridview后台修改指定列数据5.datagridview固定某个列宽6.datagridview某个列的显示隐藏7.datagr…

【设计模式】创建型模式之单例模式(饿汉式 懒汉式 Golang实现)

定义 一个类只允许创建一个对象或实例,而且自行实例化并向整个系统提供该实例,这个类就是一个单例类,它提供全局访问的方法。这种设计模式叫单例设计模式,简称单例模式。 单例模式的要点: 某个类只能有一个实例必须…

Vivado程序固化到Flash

在上板调试FPGA时,通常使用JTAG接口下载程序到FPGA芯片中,FPGA本身是基于RAM工艺的器件,因此掉电后会丢失芯片内的程序,需要重新烧写程序。但是当程序需要投入使用时不能每一次都使用JTAG接口下载程序,一般FPGA的外围会…

技术文档,they are my collection!

工作 今天这篇文章,献给一直撰写技术文档的自己。我自认为是公司中最爱写文档的人了,我们是一个不到40人的小公司,公司作风没有多么严谨,领导也不会要求我们写技术文档。但是从入职初至今,我一直保持着写技术文档…