wmic command executed in Java blocked

在Java执行下面的windows的wmic命令时,

wmic cpu get loadpercentage /value
wmic os get totalvisiblememorysize,freephysicalmemory /value
wmic process where(name="java.exe") get name,creationdate,workingsetsize,pagefileusage /value

遇到了从Process的InputStream中读执行结果时,程序阻塞在读的语句处,如下代码所示:

 

ProcessBuilder pb = new ProcessBuilder("wmic",...);  
// pb.redirectErrorStream(true);   // 注释代码1
Process p = pb.start(); 
// p.getOutputStream().close();    // 注释代码2
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));  
String tmp = null;  
  
while ((tmp = br.readline()) != null) {    //阻塞代码处
    System.out.println(tmp);  
}  
int exitValue = p.waitfor();

通过google,Java method calls the WMIC command提到根据操作系统的不同,每个Process的InputStream的大小不等,当InputStream没有足够的空间来保存执行结果时,执行结果会输出到ErrorStream当中。但是当我把上面注释代码1放开之后(另外的一个方案是创建两个线程,一个从InputStream读取执行结果,一个从ErrorStream中读取执行结果),程序仍然阻塞在read代码处。

继续google,提到了有可能因为Process是在等待输入结束的标志,在上面代码中,我们只是输入了wmic命令,但是没有结束输入,所以放开上面的注释代码2,问题解决。终于可以得到正确的输出了。

值得一提的是,当我们在创建的Process中先打开一个单独的cmd窗口,再执行上面的wmic命令时,确可以得到正确的输出结果。

 

上述代码在Win7,Win2008上可以很好的并发执行。但是在WinXP和Win2003上并发执行时,确遇到了如下的错误:

Win32 Error: The process cannot access the file because it is being used by another process

 通过观察发现,在WinXP和Win2003上执行代码时,会生成一个临时的TempWmicBatchFile.bat文件,因此就可以解释上面的现象了,因为临时文件的访问没有被同步。但是如果对每个命令执行都同步这个临时文件,当命令很多时,有可能出现大面积等待的请求。考虑到我们不需要时时得到最新的数据,因此我们对每个命令的执行结果都进行了缓存,而对命令的执行进行了同步,这样每次来的新命令就可以先拿缓存的执行结果,然后把自己放到等到命令队列中。这样就有效的避免了上面的错误。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值