2.进程与线程

news2025/1/18 11:54:13

2.进程与线程

2.1 进程与线程

进程:

  • 程序由指令和数据组成,指令要执行,数据要读写,就需要将指令加载到cpu,数据加载到内存,进程就是用来加载指令、管理IO、管理内存的
  • 当一个程序被执行,从磁盘加载代码到内存,这时就开启了一个进程
  • 进程可以视为程序的实例,大部分程序可以同时运行多个实例。

线程:

  • 一个进程有一个或多个线程
  • 一个线程就是一个指令流,将指令流中的一条条指令交给cpu执行
  • 线程是java调度的最小单位,进程作为资源分配的最小单位。

两者对比:

  • 进程基本上是相互独立的,而线程存在于进程内,是进程的一个子集

  • 进程拥有共享的资源,如内存空间,供内部的线程共享

  • 进程之间的通信比线程更复杂

    • 同一台计算机不同进程之间的通信称为IPC
    • 不同计算机之间的通信需要遵守同样的网络协议,如HTTP
  • 线程通信相对简单,因为它们共享进程内的内存

  • 线程更轻量,线程上下文切换成本比进程上下文切换低

2.2 并行与并发

并发:

在同一时间内,单核cpu同时执行多个线程

img

并行:

在同一时间,多核cpu一起执行多个线程

img

2.3 应用

应用之异步调用(案例1)

从调用的角度来讲,如果

  • 不需要等待结果返回,才能执行的是异步

同步等待

/**
 * 同步等待
 * @author xc
 * @date 2023/4/30 15:28
 */

@Slf4j
public class Sync2_3 {
    public static void main(String[] args) {
        FileReader.read("D:\\学习\\随便玩玩\\wxPush\\DEPLOY.md");
        log.debug("do other things ...");
    }
}

可以看到需要文件读完后才执行其它事情

img

  • 需要等待结果返回,才能执行的是同步

异步不要等待

/**
 * 异步不等待
 * @author xc
 * @date 2023/4/30 15:35
 */
@Slf4j
public class Async2_3 {
    public static void main(String[] args) {
        new Thread(()-> FileReader.read("D:\\学习\\随便玩玩\\wxPush\\DEPLOY.md")).start();
        log.debug("do other things ...");
    }
}

可以看到不要等待文件读完就可以做其它事情

img

1)设计

多线程可以让方法变为异步的,比如说读取磁盘文件时,假如花了30分钟,如果没有线程调度机制,那这30分钟cpu什么都做不了,其它代码都要暂停

2)结论

  • 比如在项目中,视频文件需要转换格式等比较费时间,这是开启一个新线程处理视频转化,避免阻塞主线程
  • tomcat的异步servlet也是类似的目的,让用户线程处理耗时较长的操作,避免阻塞tomcat工作线程
  • ui程序中,开启新线程来进行其它操作,避免阻塞ui线程

应用之提高效率(案例1)

充分利用多核cpu的优势,提高运行效率

计算1花费 10 ms
计算2花费 11 ms
计算3花费 9 ms
汇总花费 1 ms
  • 如果时串行需要花费31 ms
  • 如果时并行需要花费3次计算中最长的时间+1ms即可,也就是12ms

设计代码

package com.itcast;

import org.openjdk.jmh.annotations.*;

import java.util.Arrays;
import java.util.concurrent.FutureTask;

@Fork(1)
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations=3)
@Measurement(iterations=5)
public class MyBenchmark {
    static int[] ARRAY = new int[1000_000_00];
    static {
        Arrays.fill(ARRAY, 1);
    }
    @Benchmark
    public int c() throws Exception {
        int[] array = ARRAY;
        FutureTask<Integer> t1 = new FutureTask<>(()->{
            int sum = 0;
            for(int i = 0; i < 250_000_00;i++) {
                sum += array[0+i];
            }
            return sum;
        });
        FutureTask<Integer> t2 = new FutureTask<>(()->{
            int sum = 0;
            for(int i = 0; i < 250_000_00;i++) {
                sum += array[250_000_00+i];
            }
            return sum;
        });
        FutureTask<Integer> t3 = new FutureTask<>(()->{
            int sum = 0;
            for(int i = 0; i < 250_000_00;i++) {
                sum += array[500_000_00+i];
            }
            return sum;
        });
        FutureTask<Integer> t4 = new FutureTask<>(()->{
            int sum = 0;
            for(int i = 0; i < 250_000_00;i++) {
                sum += array[750_000_00+i];
            }
            return sum;
        });
        new Thread(t1).start();
        new Thread(t2).start();
        new Thread(t3).start();
        new Thread(t4).start();
        return t1.get() + t2.get() + t3.get()+ t4.get();
    }
    @Benchmark
    public int d() throws Exception {
        int[] array = ARRAY;
        FutureTask<Integer> t1 = new FutureTask<>(()->{
            int sum = 0;
            for(int i = 0; i < 1000_000_00;i++) {
                sum += array[0+i];
            }
            return sum;
        });
        new Thread(t1).start();
        return t1.get();
    }
}

运行结果,可以看到并行相较于串行性能有很大提升

img

总结

  • 单核cpu下,多线程不能实际提高程序运行效率,只是为了能够在不同的任务之间切换,不同线程轮流使用cpu,不至于一个线程总占用cpu,别的线程没办法干活

  • 多核cpu可以并行跑多个线程,但能否提高程序运行效率还是要分情况

    • 有些任务,经过精心设计,将任务拆分,并行执行,当然可以提高程序运行效率。但不是所有计算任务都能拆分
    • 也不是所有任务都需要拆分,人物的目的如果不同,谈拆分和效率没啥意义

pu下,多线程不能实际提高程序运行效率,只是为了能够在不同的任务之间切换,不同线程轮流使用cpu,不至于一个线程总占用cpu,别的线程没办法干活

  • 多核cpu可以并行跑多个线程,但能否提高程序运行效率还是要分情况

    • 有些任务,经过精心设计,将任务拆分,并行执行,当然可以提高程序运行效率。但不是所有计算任务都能拆分
    • 也不是所有任务都需要拆分,人物的目的如果不同,谈拆分和效率没啥意义
  • IO操作不占用cpu,但是我们拷贝使用的是阻塞IO,相当于不使用cpu还需要等待IO结束,没能充分利用线程,后面才有了非阻塞IO和异步IO

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

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

相关文章

大数据环境准备(二) - VMware 虚拟机系统设置

VMware 虚拟机系统设置 1.对三台虚拟机完成主机名、固定IP、SSH免密登录等系统设置 1&#xff09;配置固定IP地址 开启node1,修改主机名为node1 #切换root用户 su - #修改主机名 hostnamectl set-hostname node1关闭node1终端&#xff0c;重新打开&#xff1b; 同理开启nod…

Java页面布局

Java页面常用的布局主要有五种&#xff1a;FlowLayout、BorderLayout、GridLayout、CardLayout和NULL 1、FlowLayout 称为“流布局”&#xff0c;将组件按从左到右顺序、流动的安排到容器中&#xff0c;直到占满上方的空间时、则向下移动一行&#xff0c;Flow Layout是面板的…

13.多线程

1.实现多线程 1.1简单了解多线程【理解】 是指从软件或者硬件上实现多个线程并发执行的技术。 具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程&#xff0c;提升性能。 1.2并发和并行【理解】 并行&#xff1a;在同一时刻&#xff0c;有多个指令在多个CPU上…

Packet Tracer - 配置 IPv6 ACL

Packet Tracer - 配置 IPv6 ACL 拓扑图 地址分配表 设备 接口 IPv6 地址/前缀 默认网关 服务器 3 NIC 2001:DB8:1:30::30/64 FE80::30 目标 第 1 部分&#xff1a;配置、应用并验证一个 IPv6 ACL 第 2 部分&#xff1a;配置、应用并验证第二个 IPv6 ACL 第 1 部分…

node.js+vue鲜花销售网站

后台模块设计&#xff1a; ①用户管理功能。管理员在后台首页点击用户管理就会进入用户列表页面&#xff0c;系统会将数据库中的用户信息以列表的形式显示出来&#xff0c;管理员可以在这个页面进行用户的更新和删除操作&#xff0c;系统可以将最新更新的信息重新写入用户表中并…

Chrome浏览器更新字体看不清的最终解决方案

阿酷TONY / 2023-5-6 / 长沙 / 原创 / 实测解决 Chrome更新至版本Chrome 109.0.5414.120 字体看不清 浏览器症状&#xff1a;Chrome更新至版本Chrome 109.0.5414.120 字体看不清&#xff1b;会很细&#xff0c;在设置中选择自定义的字体&#xff0c;仍无法解决&#xff1b;…

当因果推理遇上时间序列,会碰撞出怎样的火花?

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 近年来因果推理和时间序列已经成为了数据科学领域备受瞩目的研究方向。因果推理可以帮助我们识别变量之间的因果关系&#xff0c;时间序列分析则可以便于我们理解变量随时间变化的规律。这两个方向都可以为我们…

javaScript---设计模式-封装与对象

目录 1、封装对象时的设计模式 2、基本结构与应用示例 2.1 工厂模式 2.2 建造者模式 2.3 单例模式 封装的目的&#xff1a;①定义变量不会污染外部&#xff1b;②能作为一个模块调用&#xff1b;③遵循开闭原则。 好的封装&#xff08;不可见、留接口&#xff09;&#xff1a;①…

Cacti 前台命令注入漏洞

文章目录 文档说明漏洞描述影响版本漏洞原理命令执行简单分析客户端ip伪造分析 漏洞复现下载vulhub启动环境配置攻击 复现总结修复方案原创申明 文档说明 本文作者:SwBack 创作时间:2023/4/8 0:12 知乎:https://www.zhihu.com/people/back-88-87 CSDN:https://blog.csdn.net/q…

solidity--语言基础

solidity源文件结构 // SPDX-License-Identifier: MIT pragma solidity ^0.5.2; pragma abicoder v1; import "filename"; 注释 智能合约组成 状态变量 // SPDX-License-Identifier: GPL-3.0 pragma solidity >0.4.0 <0.9.0;contract SimpleStorage {uint stor…

SD卡打不开是怎么回事?SD卡打不开里面数据怎样恢复

SD卡已经成为了移动设备和数码相机中受欢迎的存储选项之一。但是使用过程中难免会遇到一些问题&#xff0c;例如SD卡突然打不开了&#xff0c;并且无法访问其中的数据。这种情况常常让人感到烦恼和无助。但是不要紧张&#xff0c;下面我们将介绍SD卡打不开里面数据怎样恢复的方…

Yuzuki Lizard V851S开发板 –编译 OPENCV 4.5.4

1.主要参考教程地址&#xff0c;实际操作结合多个教程。 https://blog.csdn.net/Flag_ing/article/details/109508374 2.放从OPENCV RELEASE 下载的解压出来的文件&#xff0c;里面还要放对应版本的contribute 解压文件 /root/opencv-4.5.4/root/opencv-4.5.4/build6在这里要…

深入理解Java虚拟机——内存分配与回收策略

1.前言 在读这篇博客之前&#xff0c;你需要了解分代收集理论中&#xff0c;收集器应该将Java堆划分出不同的区域**&#xff0c;**然后将回收对象依据其年龄&#xff08;年龄即对象熬过垃圾收集过程的次数&#xff09;分配到不同的区域之中存储。 例如appel式回收&#xff0c…

SSM整合详细教学(上)

SSM整合详细教学&#xff08;上&#xff09; 一、SSM整合1. SSM整合配置1.1 SSM整合流程1.2 SSM整合配置1.2.1 创建工程&#xff0c;添加依赖和插件1.2.2 Spring整合Mybatis1.2.3 Spring整合SpringMVC 2. 功能模块开发2.1 数据层开发(BookDao)2.2 业务层开发(BookService/BookS…

java注解,一篇文章就够了

开篇一张图 一、定义 注解是一种标记&#xff0c;使类或接口附加额外信息&#xff0c;帮助编译器和 JVM 完成一些特定功能。 Annotation(注解)也被称为元数据(Metadata)是JDK1.5及以后版本引入的&#xff0c;用于修饰包、类、接口、字段、方法参数、局部变量等。 如&#xf…

iOS与Android应用开发的对比:如何选择最佳开发平台?

第一章&#xff1a;引言 在移动应用开发领域&#xff0c;iOS和Android是最为流行的操作系统。选择最佳的开发平台可以使开发人员更有效地开发和发布应用程序。本文将分析iOS和Android应用开发的优缺点&#xff0c;并提供一些有关如何选择最佳开发平台的建议。 第二章&#xf…

【Git基础】常用git命令(四)

文章目录 1. 处理突发事件1.1 暂存修改1.2 git stash的一些命令 2. 指定不需要git管理的文件2.1 指定不需要git管理的文件2.2 .gitignore的规则 3. 如何解决项目之间的依赖3.1 如何使用git处理项目之间的依赖3.2 submodule的使用方式3.3 如何clone submodule3.4 submodule的陷阱…

小白如何做好项目管理?看这里

做好项目管理不是一件容易的事儿&#xff0c;只有掌握了正确的技巧&#xff0c;才能事半功倍地完成项目。 下面就按照项目管理的流程来讲一讲如何做好项目管理。 项目管理是指运用系统的理论方法&#xff0c;在有限的条件和资源下&#xff0c;对项目从开始到结束的全流程进行计…

电子会议桌牌系统——基站版

一、产品特点 低功耗&#xff0c;常规使用3-5年电池寿命 支持空中唤醒&#xff0c;刷新快速&#xff0c;几秒钟内看到结果 点阵电子纸屏幕&#xff0c;视角接近180 基于Web的应用界面&#xff0c;支持跨平台操作 安装简单&#xff0c;快速布置 电池供电不需要布线 双面显…

【react从入门到精通】React兄弟组件通信方式详解(有示例)

文章目录 前言React技能树通过共同的父组件传递props使用React Context使用Redux使用EventBus写在最后 前言 在上一篇文章《React父子组件通信方式详解》中我们了解了React父子组件通信的4中方式。 本文中我们将详细了解react兄弟组件通信方式。 React技能树 React 技能树 ├…