博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于Spring Batch 执行系统命令时进程阻塞的问题
阅读量:6686 次
发布时间:2019-06-25

本文共 4093 字,大约阅读时间需要 13 分钟。

hot3.png

Spring Batch提供了SystemCommandTasklet用来执行系统命令。底层使用JDK Runtime.exec()方法,Process.waitFor()来获取运行结果。

SystemCommandTasklet部分源码:

public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {		FutureTask
systemCommandTask = new FutureTask
(new Callable
() { @Override public Integer call() throws Exception { Process process = Runtime.getRuntime().exec(command, environmentParams, workingDirectory); return process.waitFor(); } }); long t0 = System.currentTimeMillis(); taskExecutor.execute(systemCommandTask); while (true) { Thread.sleep(checkInterval); if (systemCommandTask.isDone()) { contribution.setExitStatus(systemProcessExitCodeMapper.getExitStatus(systemCommandTask.get())); return RepeatStatus.FINISHED; } else if (System.currentTimeMillis() - t0 > timeout) { systemCommandTask.cancel(interruptOnCancel); throw new SystemCommandException("Execution of system command did not finish within the timeout"); } else if (execution.isTerminateOnly()) { systemCommandTask.cancel(interruptOnCancel); throw new JobInterruptedException("Job interrupted while executing system command '" + command + "'"); } } }
Process 的Javadoc写到:

The parent process uses these streams to feed input to and get outputfrom the subprocess.  Because some native platforms only providelimited buffer size for standard input and output streams, failureto promptly write the input stream or read the output stream ofthe subprocess may cause the subprocess to block, or even deadlock.

SystemCommandTasklet没处理系统命令的输入输出。当输出大于系统限制缓冲区大小时,就会阻塞得不到返回。

例如我测试的在32位Windows下当输入超过512个字母时,进程被卡住不會结束。

修改使其处理执行系统命令时的输出(不太可能有输入所以没处理):

Process process = Runtime.getRuntime().exec(command, environmentParams, workingDirectory);                final InputStream inputStream = process.getInputStream();                final InputStream errorStream = process.getErrorStream();                Runnable r1 = new Runnable() {                    public void run() {                        BufferedReader br = null;                        try {                            if (logger.isInfoEnabled()) {                                br = new BufferedReader(new InputStreamReader(inputStream));                                for (String read = br.readLine(); read != null; read = br.readLine()) {                                    logger.info("Command out - " + read);                                }                            }                        } catch (Exception e) {                            logger.error(e.getMessage(), e);                        } finally {                            try {                                if (br != null) {                                    br.close();                                }                            } catch (IOException e1) {                                // ignore                            }                        }                    }                };                Runnable r2 = new Runnable() {                    public void run() {                        BufferedReader br = null;                        try {                            br = new BufferedReader(new InputStreamReader(errorStream));                            for (String read = br.readLine(); read != null; read = br.readLine()) {                                logger.error("Command error - " + read);                            }                        } catch (Exception e) {                            logger.error(e.getMessage(), e);                        } finally {                            try {                                if (br != null) {                                    br.close();                                }                            } catch (IOException e1) {                                // ignore                            }                        }                    }                };                r1.run();                r2.run();		 return process.waitFor();

转载于:https://my.oschina.net/POintMELOve/blog/132374

你可能感兴趣的文章
python sys模块
查看>>
PHP基础(三)函数
查看>>
我的友情链接
查看>>
linux shell脚本的使用
查看>>
c语言使用DES_ncbc_encrypt以及段错误 (核心已转储) 解决
查看>>
mockplus软件审阅功能界面图
查看>>
马哥笔记第二天
查看>>
009 牌视图实现
查看>>
Kubernetes安装
查看>>
GO语言访问ORACLE
查看>>
informix常用命令
查看>>
RHCE基础指南:Linux Security Modules
查看>>
4、AngularJS2 数据显示
查看>>
如何提高条码的安全性
查看>>
子网的划分
查看>>
打造一台称手的工作站-Ubuntu上建立PHP服务器(apache+php+mysql)
查看>>
动态规划-装配线调度
查看>>
我的友情链接
查看>>
Android布局属性详解
查看>>
小企业数据备份
查看>>