Java - 多进程编程(对比线程、API 操作)

目录

一、多进程编程

1.1、为什么要使用多进程编程

1.2、Java 中多进程编程的实现

1.2.1、前言

1.2.2、进程创建

1.2.3、进程等待

1.2.4、封装操作到一个工具类中


一、多进程编程


1.1、为什么要使用多进程编程

一个 .exe 文件执行以后,就会变成一个进程. 

多进程的由来:为了解决某些大型复杂问题,就需要把一个很大的任务,拆分成一个小的任务,进一步的,就需要使用 “多进程编程”,也就是床技安多个进程,每个进程分别负责其中一部分任务.  与此同时,也带来一个问题——“进程的 创建/销毁,比较重量(低效)”.

线程的由来:引入了线程,相比于 进程的 创建/销毁 更加高效,因此 Java 圈子中,大部分并发编程都是通过多线程的方式来实现.

什么情况下要使用多进程编程呢?

进程相比于线程最大的优势就是:进程的 “独立性”.

  • 多线程劣势:一个操作系统上,同一时刻一个进程中运行着多个线程(共用一个地址空间),某个线程挂了,就可能把整个线程带走;
  • 多进程优势:一个操作系统上,同一时刻运行着很多进程,由于不同的进程有各自的地址空间,那么即使某一个进程挂了,也不会影响到其他进程.

比如在一个 OJ 系统中,用户提交的代码就是一个独立的逻辑,整个逻辑就需要使用多进程的方式来执行.  因为用户的代码很有可能是存在问题的(一运行就崩溃),使用多线程就很有可能导致用户代码直接把整个服务器进程搞挂.

1.2、Java 中多进程编程的实现

1.2.1、前言

在操作系统的角度上(例如 Linux),提供了很多和多线程编程相关的接口,例如 进程创建、进程终止、进程等待、进程程序替换、进程间通讯.

但是在 Java 中对这些操作进行了限制,最终只提供了两个操作:进程创建 和 进程等待.

1.2.2、进程创建

通过 Runtime 实例中的 exec 方法(参数是一个字符串,相当于在 cmd 中输入了一个对应的指令)就可以创建出一个进程, 被创建出来的进程称为 “子进程”,创建子进程的进程称为 “父进程”.  咱们的服务器进程就相当于父进程,它可以有多个子进程,但是一个子进程只能有一个父进程.

一个进程在启动的时候,就会自动以下打开三个文件:

  1. 标准输入:对应到键盘.
  2. 标准输出:对应到显示器,用来正确的输出.
  3. 标准错误:对应到显示器,用来展示错误输出.

Ps:在 IDEA 中式看不到子进程的输出的,想要获取,可以手动获取.

例如,创建一个子进程运行 javac 命令,通过输入输出流,将子进程的 标准输出 和 错误输出 写到对应文件中. 

    public static void main(String[] args) throws IOException, InterruptedException {//Runtime 再 JVM 中是一个单例Runtime runtime = Runtime.getRuntime();//Process 就表示进程Process process = runtime.exec("javac");//获取子进程的标准输出和标准错误,并写道两个文件中//1.标准hou出//1) 通过 标准输入流 将子进程的标准输出读出来,写入到 stdout.txt 文件中InputStream stdoutFrom = process.getInputStream();FileOutputStream stdoutTo = new FileOutputStream("stdout.txt");while(true) {int ch = stdoutFrom.read();if(ch == -1) { //读到 EOF 为止(EOF 就是 -1)break;}stdoutTo.write(ch);}//2) 释放文件描述符stdoutFrom.close();stdoutTo.close();//2.标准错误//2) 通过标准输入流 将子进程的标准错误读出来,写入到 stderr.txtInputStream stderrFrom = process.getErrorStream();FileOutputStream stderrTo = new FileOutputStream("stderr.txt");while(true) {int ch = stderrFrom.read();if(ch == -1) {break;}stderrTo.write(ch);}//2) 释放文件描述符stderrFrom.close();stderrTo.close();}

运行后可以看到生成如下两个文件:

由于这里我只是单纯的输入 javac 命令(没有指定编译的 jar 包),因此是一个错误命令,那么就可以在 标准错误 中看到如下信息:

Ps:javac 往控制台输出的命令,再 windows 简体中文版系统中,默认是 gbk 编码,idea 默认式 utf8,打开后可能会乱码,因此只需要再 idea 提示中,通过 gbk 重新加载即可.

在 cmd 中输入 javac 也是一样的结果:

1.2.3、进程等待

在某些场景中,我们希望父进程等待子进程执行完毕以后,再执行后续的代码. 

例如,OJ 系统就需要让用户提交代码,然后编译执行代码,再把执行结果的响应返回给用户.

具体实现如下:

通过 Process 类中的 waitFor 方法实现进程等待,父进程执行到 waitFor 的时候就会阻塞,知道子进程执行完毕为止(类似 Thread.join). 最后会返回一个退出码,表示子进程执行结果是否 ok,正常退出就返回 0,异常退出(子进程执行过程中抛异常了)就非0.

        //进程等待int exitCode = process.waitFor();System.out.println(exitCode);

1.2.4、封装操作到一个工具类中

通常,我们会将进程创建和等待封装到一个工具类中去使用.

public class CommandUtil {/*** @param cmd 进程要执行的命令* @param stdout 标准输出文件名 + 后缀* @param stderr 标准错误文件名 + 后缀* @return 进程等待后返回的状态码*/public static int run(String cmd, String stdout, String stderr) {try {//1.获取 Runtime 实例,执行 exec 方法Runtime runtime = Runtime.getRuntime();Process process = runtime.exec(cmd);//2.获取 标准输出if(stdout != null) {InputStream stdoutFrom = process.getInputStream();FileOutputStream stdoutTo = new FileOutputStream(stdout);while(true) {int read = stdoutFrom.read();if(read == -1) {break;}stdoutTo.write(read);}stdoutFrom.close();stdoutTo.close();}//3.获取 标准错误if(stderr != null) {InputStream stderrFrom = process.getErrorStream();FileOutputStream stderrTo = new FileOutputStream(stderr);while(true) {int read = stderrFrom.read();if(read == -1) {break;}stderrTo.write(read);}stderrFrom.close();stderrTo.close();}//4.进程等待return process.waitFor();} catch (Exception e) {e.printStackTrace();}//返回异常的状态码return 1;}//测试public static void main(String[] args) {int result = run("javac", "stdout.txt", "stderr.txt");System.out.println(result);}}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vscode使用CSScomb插件

1. 安装 在设置中搜索csscomb,把Csscomb: Format On Save勾上 然后去edit in settings.json配置 2.使用 2.1 用官网提供的三种方法 https://github.com/csscomb/csscomb.js/tree/master/config 2.2 自定义 CSS 书写顺序规则可以参考这个荐腾讯 AollyTeam 团队的…

Java SSL/TLS证书认证逻辑

前言 最近做项目使用httpclient转发https请求,但是遇到一些坑,尤其是证书的认证,证书认证一般都是单向的,除非相互访问,证书一般基于host,但是如果访问需要ip,那么JDK默认的认证就会不通过&…

emqx 启动正常,但是1883端口无法telnet,emqx无法正常工作

emqx一直正常工作,后面突然就不工作了,查找日志,发现报错说设备空间不足,但是我记得华为云SSD从40G扩容到500G,不至于空间不足,于是运行df -Dh确实显示只有40G,运行lsblk确实有500G,…

基于Arrow的轻量线程池

基于Arrow的轻量线程池 大家好,我是光城,最近花了几周业余时间,开发出这款轻量线程池,代码也全部开源啦,欢迎大家star。 本线程池的设计与实现会有涉及非常多的知识,这些内容也都会以视频的方式分享在知识星…

每个epoch的溯源(MNE)

每个epoch的溯源: from mne.minimum_norm import apply_inverse_epochs stcs apply_inverse_epochs(epochs,inverse_operator,lambda2,method,pick_ori"normal"# naveevoked.nave, )

从零开始构建基于YOLOv5的目标检测系统

本博文从零开始搭建基于YOLOv5模型的目标检测系统(具体系统参考本博主的其他博客),手把手保姆级完成环境的搭建。 (1)首先Windows R输入cmd命令后打开命令窗口,进入项目目录,本博文以野生动物…

交换机控制在同一个网段内的终端,用hybrid接口实现不同的IP通和不通。

实验效果:pc1和pc2不能通,但pc1和pc2分别可以和pc3通。 通过这个实验可以彻底掌握数据包在交换机上的进去的类型状态。 sw1配置: [sw1]dis current-configuration sysname sw1 vlan batch 10 20 100 interface GigabitEthernet0/0/1 port h…

计算机服务器中了勒索病毒怎么解决,勒索病毒解密流程,数据恢复

计算机服务器中了勒索病毒是一件非常令人头疼的事情,勒索病毒不仅会加密企业服务器中的数据,还会对企业计算机系统带来损害,严重地影响了企业的正常运转。最近,云天数据恢复中心工程师总结了,今年以来网络上流行的勒索…

Vue3中使用富文本编辑器

在vue3中我们可以使用wangeditor/editor、wangeditor/editor-for-vue来实现其功能 npm地址:https://www.npmjs.com/package/wangeditor/editor-for-vue/v/5.1.12?activeTabreadme 官网:Editor 1. 安装 pnpm add wangeditor/editor # 或者 npm inst…

卷积神经网络CNN学习笔记-卷积计算Conv2D函数的理解

目录 1.全连接层存在的问题2.卷积运算3.填充(padding)3.1填充(padding)的意义 4.步幅(stride)5.三维数据的卷积运算6.结合方块思考7.批处理8.Conv2D函数解析9.conv2d代码9.1 stride19.2 stride2 参考文章 1.全连接层存在的问题 在全连接层中,相邻层的神经元全部连接…

饲料化肥经营商城小程序的作用是什么

我国农牧业规模非常高,各种农作物和养殖物种类多,市场呈现大好趋势,随着近些年科学生产养殖逐渐深入到底层,专业的肥料及饲料是不少从业者需要的,无论城市还是农村都有不少经销店。 但在实际经营中,经营商…

Jetson nano 安装Ubuntu20.04系统

一、下载Ubuntu20.04镜像 下载地址:点击 二、格式化SD卡 (1)工具:SDFormatter (2)工具下载-百度网盘: 链接:https://pan.baidu.com/s/1DcwsGzmqrWwFmzpCV7VCyA 提取码&#xff1a…

bp(back propagation)

文章目录 定义过程前向传播计算过程计算损失函数(采用均方误差MSE)反向传播误差(链式法则)计算梯度更新参数 简单实例 定义 反向传播全名是反向传播误差算法(Backpropagation),是一种监督学习方…

python二次开发Solidworks:修改实体尺寸

立方体原始尺寸:100mm100mm100mm 修改后尺寸:10mm100mm100mm import win32com.client as win32 import pythoncomdef bin_width(width):myDimension Part.Parameter("D1草图1")myDimension.SystemValue width def bin_length(length):myDime…

【吞噬星空】又被骂,罗峰杀人目无法纪,但官方留后手,增加审判戏份

Hello,小伙伴们,我是小郑继续为大家深度解析国漫吞噬星空资讯。 吞噬星空动画中,罗峰复仇的戏份,简直是帅翻了,尤其是秒杀阿特金三大巨头,让人看的也是相当的解气,相当的爽,一点都不拖沓&#x…

TCP为什么需要三次握手和四次挥手?

一、三次握手 三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包 主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备 过程如下&#xff…

力扣每日一题51:N皇后问题

题目描述: 按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上,并且使皇后彼此之间不能相互攻击。 给你一个整数 n ,返回所有不同的 n 皇后问…

bitbucket.org 用法

这个网站需要魔法,注册完成后添加厂库时间2023.10 图1 图2 第二张图 ,不要.gitignore文件 sourcetree 1,创建前端项目 npm create vitelatest 2.打开vscode创建本地Git 看到Git代提交的文件 sourcetree,新建 已存在的本地厂库 提交到Git 添…

linux基础IO

文章目录 前言一、基础IO1、文件预备知识1.1 文件类的系统调用接口1.2 复习c语言接口 2、文件类的系统调用接口2.1 open系统调用2.2 close系统调用2.3 write系统调用2.4 read系统调用 3、文件描述符3.1 文件描述符fd介绍3.2 文件描述符fd分配规则与重定向3.3 重定向原理3.4输入…

(八)vtk常用类的常用函数介绍(附带代码示例)

vtk中类的说明以及函数使用 https://vtk.org/doc/nightly/html/annotated.html 一、vtkObject派生类 1.vtkPoints 点 InsertNextPoint(double, double, double):插入点。 2.vtkCellArray 单元数组 InsertNextCell (vtkIdType npts, const vtkIdType *pts)&…