[JAVAEE]—进程和多线程的认识

news2024/11/19 1:53:07

文章目录

  • 什么是线程
    • 什么是进程
      • 进程的组成
      • 什么是pcb
    • 进程概括
    • 线程
      • 线程与进程的关系
      • 线程的特点
  • 创建线程
    • 创建线程方法
    • 创建线程的第二种方法
      • 对比
    • 其他的方式
      • 匿名内部类创建线程
      • 匿名内部类创建Runable的子类
      • lambda表达式创建一个线程
  • 多线程的优势

什么是线程

什么是进程

首先想知道什么是线程就得先搞明白什么是进程,关于进程呢,我们说进程是系统进行资源分配的基本单位但是光知道这句话远远不够,因为我们不知道什么是资源分配,我们可以简单的将计算机理解为钱包。
那么资源就是钱包里的钱,至于进程就是我们要做的事情或者说要买的东西,比如说旅游啊买衣服啊。我们把资源(也就是钱)进行了划分,那一部分用来旅游哪一部分用来买衣服做了明确的划分,而这就是资源分配,至于买衣服啊之类的就是我们的进程。

进程的组成

进程是由自己的代码和pcb组成的我们上面说了,进程就是我们要执行的任务,那么在计算机中计算机要执行的任务其实就是我们写的程序,因此我们可以这样理解我们运行了一个程序那么这个程序在我们后台中就是一个进程了。他也正如其名字一样,进行中的程序。由此我们可以知道进程就是我们运行的代码,那么刚刚说的pcb又是什么呢?

什么是pcb

我们运行一个代码那么操作系统就要管理我们运行的程序代码怎么管理呢?那就是先描述再组织,相信大家对这句话应该不陌生吧。那么我们想要描述一个进程该怎么办?就像我们想要描述一个人我们需要把这个人的各种特点记录起来一样,描述进程也是这样把这个进程的各种特点记录下来,而这些特点用一个结构体保存下来这个结构体就是pcb,因此一个进程由什么组成呢?那就是自己的代码+pcb

进程概括

简单来讲进程的概念主要你有两点:

一:进程是一个运行中的实体每一个进程都有自己的内存空间包括堆栈啊等等
二:进程是一个执行的程序,他也需要被管理为了管理它系统中有一个用于存储其基本信息的结构体叫做PCB

线程

什么是线程呢?有了上面的概念我们就可以来讲一下线程了,如果说进程是进行资源分配的基本单位的话那么线程就是**线程是CPU独立运行和独立调度的基本单位。**有些同学可能就蒙了啊什么是cpu独立运行和独立调度呢?我们在购买电子设备的时候我们知道cpu会说他是几核几核的这些核心就是我们用来运行线程的。那么知道这些是不够的,对于初学者来说还是不知道线程到底是什么他跟进程到底有什么关系啊?那么我们现在就来解决一下这个疑惑。

线程与进程的关系

我们上面说了进程就是一个任务,我们去购物,旅游这样的一个任务,那么线程是什么呢?线程则是任务的步骤或者说是任务的分支,就像我们为了完成购物这个任务我们需要分成以下几个步骤那就是第一乘车去商场,第二挑选商品,第三付账,那么以上为了完成这个任务创建的分支就是线程,由此可见线程其实就是进程的分支.那么我们现在就知道为什么了解线程之前要了解进程了。
总结一下目前已知的知识点

线程是进程的一个分支
线程被创建出来是为了执行某个任务
线程是cpu独立运行和独立调度的基本单位.

线程的特点

通过以上的知识我们可以知道线程的哪些特点呢?

线程是轻量级的进程
线程没有独立的地址空间
线程依附于进程进程可以拥有多个线程

创建线程

通过以下的代码来感受以下线程和普通程序的区别吧

class Mytheard extends Thread{

    public void run(){
        while (true){
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("我是一个线程");
        }
    }
}
public class Main {
    public static void main(String[] args) throws InterruptedException{
        Thread ne=new Mytheard();
        ne.start();
        while(true){
            ne.sleep(1000);
            System.out.println("Hello world!");
        }
    }
}

运行截图如下
在这里插入图片描述
我们可以看到他跟普通的函数调用不一样的就是主函数和我们创建的这个是在并发执行的这个也就是其中最主要的一个区别.

创建线程方法

在这个代码中呢我们调用了一个start方法.这个方法其实就是创建一个线程并且在创建完成之后呢自动调用我们实现的run函数那么有些同学可能看不出来这到底跟我直接new一个Mythread对象调用这个run有什么区别我们再来看一下下面的代码

class Mytheard extends Thread{

    public void run(){
        while (true){
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("我是一个线程");
        }
    }
}
public class Main {
    public static void main(String[] args) throws InterruptedException{
        Thread ne=new Mytheard();
        ne.run();
        while(true){
            ne.sleep(1000);
            System.out.println("Hello world!");
        }
    }
}

这个代码运行起来呢我们可以发现他是只会执行一个while循环的.并不能做到并发执行,很明显这并不符合我们开发的一个目的.
在这里插入图片描述
那么这里面start和run的区别其实就是有没有创建一个线程.而这个方法其实只是我们开发中创建线程的一种方法

创建线程的第二种方法

	实现Runable接口

Runable 呢是我们的一个接口,相信未来搞开发的肯定听过一句话叫做高内聚低耦合.而我们的大佬呢考虑到如果将任务和线程的创建绑定在一起就不符合这个高内聚低耦合的精神了为了解耦呢就创建了这样一个方式去创建线程代码如下

class MytheardRunable implements Runnable{

    public void run(){
        while (true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("我是一个线程");
        }
    }
}
public class Main {
    public static void main(String[] args) throws InterruptedException{
        Thread t=new Thread(new MytheardRunable());
        t.start();
        while(true){
            Thread.sleep(1000);
            System.out.println("Hello world!");
        }
    }
}

那么这个代码我们发现不同地方除了继承了这个接口之外还有就是我们new对象的时候我们的那里加上了一个参数.我们翻译以下就是创建一个线程对象,并且接下来要执行的任务是这个任务.
在这里插入图片描述
我们看一下Thread构造方法的源代码也可以发现这里面也确实有一个参数就是这个接口的参数.
在这里插入图片描述
并且我们查看这个接口内部的方法的时候也可以发现这个方法内部也只实现了一个run方法我们也只需要重写一个run方法即可.

对比

对比上面两种方法:
继承 Thread 类, 直接使用 this 就表示当前线程对象的引用.
实现 Runnable 接口, this 表示的是 MyRunnable 的引用. 需要使用 Thread.currentThread()

其他的方式

那么基础较好的同学看到上面的代码可能就会想到别的方式了那就是lamdba和匿名内部类的方式而事实上这两种方式也确实是一种不错的方式去创建线程代码如下

匿名内部类创建线程

public class Main {
    public static void main(String[] args) throws InterruptedException{
        Thread t=new Thread(){
            @Override
            public void run() {
                while(true){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println("我是匿名内部类创建的一个线程");
                    
                }
            }
        };
        t.start();
        while(true){
            Thread.sleep(1000);
            System.out.println("Hello world!");
        }
    }
}

匿名内部类创建Runable的子类

public class Main {
    public static void main(String[] args) throws InterruptedException{
        Thread t=new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println("我是Runable匿名内部类创建的一个线程");

                }
            }
        });
        t.start();
        while(true){
            Thread.sleep(1000);
            System.out.println("Hello world!");
        }
    }
}

lambda表达式创建一个线程

public class Main {
    public static void main(String[] args) throws InterruptedException{
        Thread t=new Thread(()->{
            while(true){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("我是lambda表达式创建出的线程");
            }
        });
        t.start();
        while(true){
            Thread.sleep(1000);
            System.out.println("Hello world!");
        }
    }
}

多线程的优势

通过上面的例子我们知道了多线程和普通代码区别的就是可以并发执行,那么可以并发执行这就大大的提高了我们的程序运行效率,其实就像我们做事情是一样的,我们可以在做一件事情的同时去做另一个事情并且两个事情互不干扰,效率达到了很大的提升.

	和爱的人一起努力.

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

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

相关文章

iOS 判断触摸位置是否在图片的透明区域

装扮功能系列: Swift 使用UIScrollerView 实现装扮功能(基础)Swift 使用UIScrollerView 实现装扮功能(拓展)iOS 判断触摸位置是否在图片的透明区域 背景 在装扮功能中,一般都是长按使道具进入编辑状态&…

ES分布式搜索-使用RestClient操作索引库

RestClient操作索引库 1、什么是RestClient? ES官方提供了各种不同语言的客户端,用来操作ES。这些客户端的本质就是组装DSL语句,通过http请求发送给ES。官方文档地址:Elasticsearch Clients官方文档 2、利用JavaRestClient实现…

软考高级:软件架构风格-闭环控制概念和例题

作者:明明如月学长, CSDN 博客专家,大厂高级 Java 工程师,《性能优化方法论》作者、《解锁大厂思维:剖析《阿里巴巴Java开发手册》》、《再学经典:《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

Python 查找PDF中的指定文本并高亮显示

在处理大量PDF文档时,有时我们需要快速找到特定的文本信息。本文将提供以下三个Python示例来帮助你在PDF文件中快速查找并高亮指定的文本。 查找并高亮PDF中所有的指定文本查找并高亮PDF某个区域内的指定文本使用正则表达式搜索指定文本并高亮 本文将用到国产第三方…

Java学习笔记(11)

面向对象进阶 Static 静态变量 所有对象一起共享,就用static修饰 不属于对象,属于类的 可以用 类名.静态变量 “”;赋值 但是 对象.静态变量也可以访问到内容 Static内存图 Student这个类的字节码文件加载到方法区,并在内…

企业计算机服务器中了eking勒索病毒怎么办?Eking勒索病毒解密工具流程

网络数据安全问题一直是众多企业关心的主要话题,网络在为企业提供便利的同时,也为企业数据安全带来未知的隐患。近日,云天数据恢复中心接到许多企业求助,企业的计算机服务器遭到了eking勒索病毒攻击导致企业计算机服务器系统瘫痪无…

操作系统——cpu、内存、缓存介绍

一、内存是什么 内存就是系统资源的代名词,它是其他硬件设备与 CPU 沟通的桥梁, 计算机中的所有程序都在内存中运行。其作用是暂时存放CPU的运算数据,以及与硬盘交换的数据。也是相当于CPU与硬盘沟通的桥梁。只要计算机在运行,CP…

YOLOv9实例分割教程|(一)训练教程

专栏介绍:YOLOv9改进系列 | 包含深度学习最新创新,主力高效涨点!!! 一、创建数据集及数据配置文件 创新一个文件夹存放分割数据集,包含一个images和labels文件夹。标签格式如下所示: 创新数据集…

Netty线程模型详解

文章目录 概述单Reactor单线程模型单Reactor多线程模型主从Reactor多线程模型 概述 Netty的线程模型采用了Reactor模式,即一个或多个EventLoop轮询各自的任务队列,当发现有任务时,就处理它们。Netty支持单线程模型、多线程模型和混合线程模型…

1、计划任务介绍

Windows计划任务介绍 1、含义: 简单点就是定时执行任务。 在许多场景下,我们定时执行一些任务。比如:定时拉取、备份文件,更新代码等等操作。 WinR打开运行框,输入:control schedtasks,就会…

SAR ADC系列4——比较器的Transient noise仿真--等效输入噪声

仿真出等效输入噪声 加一个快于实际工作的时钟频率;在输入端加一个DC的差(比如一端是0.5VDD,另外一端加0.5VDD0.2MV)计算仿真时间内的correct counting number,比如时钟频率是200MHz,仿真时间是5us,那么应…

IMX8MM -- Yocto构建遇见的错误及解决方法:

IMX8MM Yocto构建遇见的错误及解决方法: 1 bison-3.0.4 error2 Opencv BB_NO_NETWORK Error :3 Yocto构建时出现U-boot 问题4 Yocto构建时出现Linux kernel编译问题5 wayland-native6 cross-localedef-native7 wayland-protocols8 mesa 硬件:…

[论文精读]Dynamic Coarse-to-Fine Learning for Oriented Tiny Object Detection

论文网址:[2304.08876] 用于定向微小目标检测的动态粗到细学习 (arxiv.org) 论文代码:https://github.com/ChaselTsui/mmrotate-dcfl 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&…

android MMKV数据持久化缓存集合

前言 最近在使用mmkv缓存的时候 发现没有集合缓存 非常不方便 自己写一个方法 MMKV public class MmkvUtils {private MmkvUtils() {throw new UnsupportedOperationException("u cant instantiate me...");}public static void init() {MMKV.initialize(LeoUtils…

C语言从入门到熟悉------第三阶段

数组 什么是数组呢?顾名思义数组就是很多数的组合!那么这些数有没有什么要求呢?是不是不管什么数组合在一起都是数组呢?第一,这些数的类型必须相同!第二,这些数在内存中必须是连续存储的。也就…

力扣思路题:重复的子字符串

注意比较j与j-i是否相同 bool repeatedSubstringPattern(char* s) {int i;int nstrlen(s);bool flag;for(int i1;i<n/2;i){if(n%i0){flagtrue;}for(int ji;j<n;j){if(s[j]!s[j-i]){flagfalse;break;}}if(flagtrue){return true;}}return false; }

Python爬虫基础学习-互联网、HTTP与HTML

互联网或者叫国际网&#xff08;Internet&#xff09;&#xff0c;是指网络与网络之间所串连成的庞大网络&#xff0c;这些网络以一组标准的网络TCP/IP协议族相连&#xff0c;连接全世界几十亿个设备&#xff0c;形成逻辑上的单一巨大国际网络。它是由从地方到全球范围内几百万…

【算法】一类支持向量机OC-SVM(2)

【算法】一类支持向量机OC-SVM&#xff08;2&#xff09; 前言纠正内容数据集创建方式适应度函数 新增内容散点图示例模型散点图展示 前言 在上则博文【算法】一类支持向量机OC-SVM&#xff08;1&#xff09; 中&#xff0c;我们提及到了蜂群算法优化一类支持向量机超参数模型…

gpt-4-all模型中转实现

最近才完成这个功能&#xff0c;相信知道这个模型的人&#xff0c;应该已经熟悉了。这是我的中转&#xff1a;openai-api Chatbox配置如下&#xff1a; 模型测试&#xff1a; 1&#xff09;图片生成 2&#xff09;文件分析&#xff0c;链接读取&#xff1a;

WWW2024 | PromptMM:Prompt-Tuning增强的知识蒸馏助力多模态推荐系统

论文&#xff1a;https://arxiv.org/html/2402.17188v1 代码&#xff1a;https://github.com/HKUDS/PromptMM 研究动机 多模态推荐系统极大的便利了人们的生活,比如亚马逊和Netflix都是基于多模态内容进行推荐的。对于研究,人们也遵循工业界的趋势,进行modality-aware的用户…