正常来说java调用shell命令就是用

String[] cmdAry = new String[]{"/bin/bash","-c",cmd}
Runtime.getRuntime().exec(cmdAry);

实际上就是创建个子进程去执行这个命令。

问题来了: 如果我执行下面这句命令

exp system/manager buffer=64000  file=/home/oracle/beifen/beifen.dmp  FULL=Y

这种输出日志量特别大的命令,就会出现卡死,一直不动,后来了解到 子进程产生的输出日志都会写到窗口里,因为窗口有缓存大小限制,

到达一定程度时就会卡死,导致死锁,后来百度了其他作者的资料才发现,这种直接调用exec用法是不好的,数据量小可能体现不出来,

数据量大的时候 就会直接缓存爆满 子进程就会卡死,所以我们可以创建2个线程来消费子进程运行shell命令产生的日志,正确用法如下

public class TestController {

    @GetMapping("/exp")
public void addHomePage(String cmd) throws InterruptedException, IOException {
//创建子进程调用shell命令
new MyThread(cmd).start();
}
} class MyThread extends Thread {
String cmd;
MyThread(String cmd)
{
this.cmd = cmd;
}

public void run(){
Process proc = null;
try {
       String[] cmdAry = new String[]{"/bin/bash","-c",cmd}
proc = Runtime.getRuntime().exec(cmdAry);
} catch (IOException e) {
e.printStackTrace();
}
//接收子进程的汇报信息和错误信息,避免阻塞
new StreamGobbler(proc.getInputStream(),"INFO").start();
new StreamGobbler(proc.getErrorStream(),"ERROR").start(); //获取子进程执行结果状态
int status= 0;
try {
status = proc.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (status == 0){
System.out.println("执行完毕");
}else
System.out.println("执行失败"); //销毁子进程
proc.destroy();
}
} class StreamGobbler extends Thread
{
InputStream is;
String type; StreamGobbler(InputStream is, String type)
{
this.is = is;
this.type = type;
} public void run()
{
try
{
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line=null;
while ( (line = br.readLine()) != null)
System.out.println(type + ">" + line);
} catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}

这样就可以了  记得以后调用shell命令都用这种形式

java 执行shell命令遇到的坑的更多相关文章

  1. java 执行shell命令及日志收集避坑指南

    有时候我们需要调用系统命令执行一些东西,可能是为了方便,也可能是没有办法必须要调用.涉及执行系统命令的东西,则就不能做跨平台了,这和java语言的初衷是相背的. 废话不多说,java如何执行shell ...

  2. Android Java执行Shell命令

    最新内容建议直接访问原文:http://www.trinea.cn/android/android-java-execute-shell-commands/ 主要介绍Android或Java应用中如何 ...

  3. java执行Shell命令

    java程序中要执行linux命令主要依赖2个类:Process和Runtime首先看一下Process类:ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机 ...

  4. [Java] Java执行Shell命令

    Methods ProcessBuilder.start() 和 Runtime.exec() 方法都被用来创建一个操作系统进程(执行命令行操作),并返回 Process 子类的一个实例,该实例可用来 ...

  5. java 执行shell命令

    Runtime.getRuntime().exec http://blog.csdn.net/heyetina/article/details/6555746

  6. 第3节 sqoop:7、通过java代码远程连接linux执行shell命令

    数据库的数据同步软件sqoop 数据同步 关系型数据库到大数据平台 任务:sqoop 是批量导入数据太慢,如何做到实时的数据同步 实时的数据同步工具: canal 阿里开源的一个数据库数据实时同步的软 ...

  7. Android 用java语言执行Shell命令

    最近项目中需要用到java语言来执行shell命令,在网上查了资料, 把自己在项目里用到的命令整理成了工具类开放给大家,希望对大家有用.功能不全,后期我会慢慢添加整合. public class Sh ...

  8. Java 实现 ssh命令 登录主机执行shell命令

    Java 实现 ssh命令 登录主机执行shell命令 1.SSH命令 SSH 为 Secure Shell 的缩写,由 IETF 的网络小组(Network Working Group)所制定:SS ...

  9. 【Hadoop离线基础总结】通过Java代码执行Shell命令

    通过Java代码执行Shell命令 需求 在实际工作中,总会有些时候需要我们通过java代码通过远程连接去linux服务器上面执行一些shell命令,包括一些集群的状态管理,执行任务,集群的可视化界面 ...

随机推荐

  1. docker四种模式

    1 host模式众所周知,Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,MountNamespace隔离文件系统,Network Name ...

  2. 一步一步超级详细的zabbix安装教程

    安装说明: 1. 虚拟机上安装两台全新Linux: zabbix-server:192.168.255.128 zabbix-agent :192.168.255.129 2. zabbix-serv ...

  3. HTML(前端web)

    目录 一:HTML前端 1.什么是前端? 2.什么是后端? 3.什么是HTML? 4.HTML不是什么? 5.前端的学习流程 6.BS架构 7.搭建服务器 简易(浏览器访问) 8.浏览器访问报错原因 ...

  4. linux中rpm安装

    目录 一:linux中rpm安装 1.rpm简介 2.区别 3.RPM命令五种基本模式 二:RPM安装全面解析 1,下载软件包 2, 安装软件包 3, 尝试卸载 4, 更新(升级) 5,软件包名称: ...

  5. R-B Tree

    1.简介 R-B Tree,全称Red-Black Tree,又称为"红黑树",为一种自平衡二叉查找树(特殊的平衡二叉树,都是在插入和删除操作时通过特定操作保持二叉树的平衡,从而获 ...

  6. .NET 5.0 Docker 镜像 错误修复方法

    在给eshopondapr 打镜像的时候碰到了3个错误 1.restore: Received an unexpected EOF or 0 bytes from the transport stre ...

  7. 「CTSC 2011」排列

    「CTSC 2011」排列 要求不存在公差为 A 或者公比为 B 的子列,那么实际上可以把该问题转化为求一个图的最优拓朴序. 任意差为 A 或者比为 B 的两个数连一条边. 求一个合法序列的答案可以用 ...

  8. iconv(gb2312<->utf-8)

    转载请注明来源:https://www.cnblogs.com/hookjc/ unix下安装PHP的module,需要重新编译PHP,Windows下安装模板,只需将php.ini里的配置打开相应的 ...

  9. html重点标签总结

    一. iframe 的学习 iframe通俗的的理解就是,可以在页面里面嵌套新的页面 它的使用会使页面变卡,一般会有一个固定的尺寸,默认的.他也属于可替换元素行列.我们可以通过CSS来改变尺寸 fra ...

  10. NSString 类介绍及用法

    1.NSString常见方法 NSString是 Objective-C 中核心处理字符串的类之一 创建常量字符串,注意使用"@"符号. NSString *astring = @ ...