- 浏览: 66243 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
monkeyVon:
感谢楼主分享~不过有个地方有点错误,majorityCnt(c ...
《机器学习实战》3:决策树 -
liu765023051:
很好,感谢楼主分享了。
2013年11月15日-DWR的工作原理
有些时候我们需要在Java程序中调用一些exe程序或是脚本语言,例如.bat python 等。Java提供了Runtime对象及一些方法。
1、JAVA API:
首先,看一下Runtime的API:
Every Java application has a single instance of class Runtime that allows the application to interface with the environment in which the application is running. The current runtime can be obtained from the getRuntime method.
有两个方法需要说一下:
(1)public static Runtime getRuntime()
Returns the runtime object associated with the current Java application. Most of the methods of class Runtime are instance methods and must be invoked with respect to the current runtime object.
这个函数用来返回当前java应用程序的Runtime对象,是一个静态函数。用户可以通过类直接调用(Runtime.getRuntime())。
(2)用来执行脚本的函数
public Process exec(String command)throws IOException
Executes the specified string command in a separate process with the specified environment and working directory.
该方法用来执行字符串形式的系统命令,返回一个管理子进程的Process对象
(3)Process对象:该对象有以下几个方法,用来操作子进程
abstract void destroy()
Kills the subprocess.
abstract int exitValue()
Returns the exit value for the subprocess.
abstract InputStream getErrorStream()
Gets the error stream of the subprocess.
abstract InputStream getInputStream()
Gets the input stream of the subprocess.
abstract OutputStream getOutputStream()
Gets the output stream of the subprocess.
abstract int waitFor()
causes the current thread to wait, if necessary, until the process represented by this Process object has terminated.
2、使用方法:
Process p = null; try { p = Runtime.getRuntime().exec("notepad.exe"); } catch (Exception e) { e.printStackTrace(); } System.out.println("我想被打印...");
这样简单的运行第三方程序之后,会造成子进程还没有运行完,java程序就向下接着运行了。这对一些想等待第三方程序执行完的用户来说不合理,这里就要用到waitFor()方法。
在以上程序的.exec("")后,添加代码:
p.waitFor();
但是,这样会出现必须要等我们把记事本关闭打印语句才会被执行。并且你不碰手动关闭它那程序就一直不动,程序出现了挂起的现象。看一下这个函数的API:
Causes the current thread to wait, if necessary, until the process represented by this Process object has terminated. This method returns immediately if the subprocess has already terminated. If the subprocess has not yet terminated, the calling thread will be blocked until the subprocess exits.
也就是说,等到当前的进程会等待子进程结束,如果子进程停止,该方法立即被返回。但是直接调用这个方法会导致当前线程阻塞,直到退出子进程。
产生阻塞的原因:因为本地的系统对标准输入和输出所提供的缓冲池有效,所以错误的对标准输出快速的写入何从标准输入快速的读入都有可能造成子进程的所,甚至死锁。好了,问题的关键在缓冲区这个地方:可执行程序的标准输出比较多,而运行窗口的标准缓冲区不够大,所以发生阻塞。接着来分析缓冲区,哪来的这个东西,当Runtime对象调用exec(cmd)后,JVM会启动一个子进程,该进程会与JVM进程建立三个管道连接:标准输入,标准输出和标准错误流。假设该程序不断在向标准输出流和标准错误流写数据,而JVM不读取的话,当缓冲区满之后将无法继续写入数据,最终造成阻塞在waitfor()这里。
3、解决程序挂起,查了网上说的,基本都是开启两个线程,读取进程的输出和错误内容。
代码如下:
public class TestProcess { /** * @param args */ public static void main(String[] args) { TestProcess test=new TestProcess(); test.openNotepad(); } public void openNotepad(){ try { Process p = Runtime.getRuntime().exec("notepad.exe"); StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), "Error"); StreamGobbler outputGobbler = new StreamGobbler(p.getInputStream(), "Output"); //开启两个线程读缓冲区内容 errorGobbler.start(); outputGobbler.start(); p.waitFor(); p.destroy(); } catch (Exception e) { e.printStackTrace(); } } 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) { if (type.equals("Error")) System.out.println(line); else System.out.println(line); } } catch (IOException ioe) { ioe.printStackTrace(); } } } }
这个方法就解决了调用waitFor()方法阻塞无法返回的问题。
发表评论
-
Java内存模型笔记(一)
2017-02-17 14:05 0JVM内存模型:主内存和线程独立的工作内存 Java内存 ... -
Java面试题系列1
2015-01-22 22:02 0第一部分 JVM 和 内存模式 垃圾回收 第二部分 数据 ... -
面试中会问到的Java基础问题
2014-05-15 23:01 01 String/StringBuilder/StringBu ... -
Java——判断点是否在四面体内/立方体内
2014-03-10 14:16 42681、假设有一个四面体,四个顶点定义: V1 = (x1, ... -
java 求矩阵乘法及行列式的值
2014-03-10 11:19 5623最近用到矩阵的数学计算,写了两个简单的程序,贴在这里: 1、 ... -
养成良好的开发习惯(Java)
2014-03-05 10:13 01、使用Eclipse中的注释模板 打开Eclipse,有 ... -
Java设计模式——策略模式
2014-03-02 00:20 637《Thinking in Java》看了一大部分,发现其 ... -
Java学习笔记——数组
2014-01-05 12:56 651现在已经很少用到 ... -
Java学习笔记——持有对象
2013-12-14 16:53 663通常,在程序运行之前是不知道所需对象的类型及数量的,为解决 ... -
Java学习笔记——多态、接口、内部类
2013-12-08 23:31 547大部分内容都是摘自《Thinking in Java》 ... -
Java学习笔记——复用类
2013-12-02 23:50 869Java中实现代码复用的两 ... -
log4j的用法
2013-12-03 10:06 749在调试程序中最常用的 ... -
Java学习笔记——初始化和清理
2013-11-24 14:13 6851.构造器 (1)默认构造器:Java同样采用构造器的方式保 ... -
Java学习笔记——操作符
2013-11-20 23:06 698操作符对所有编程 ... -
ArrayList 的复制
2013-11-18 10:28 837今天在使用ArrayList的时候遇到一个问题,搞了 ...
相关推荐
Runtime Permission Simpliest way to ask runtime permissions on Android, choose your way : Kotlin Kotlin with Coroutines RxJava Java8 Java7 No need to override Activity or ...
而runtime exception则用来指示一种调用方本身无法处理或恢复的程序错误。 checked exception迫使你捕获它并处理这种异常情况。以java.net.URL类的构建器(constructor)为例,它的每一个构建器都会抛出...
Oracle调用第三方外部程序。Oracle使用sqluldr2快速导出大批量数据,然后用winrar压缩后发送邮件。 源码 java source create or replace and compile java source named jv_run_extpro as import java.io.*; ...
1. java.lang.IllegalStateException: No wrapped connection. 2.java.lang.IllegalStateException: Adapter is detached. 原因: 1.单线程一次执行一个请求可以正常执行,如果使用多线程,同时执行多个请求时就会...
第二种,使用第三方的jar包进行获取,通过直接调用操作系统的api来获取系统相关数据。本文则主要介绍一种通过Hyperic-hq产品的基础包sigar.jar来实现服务器状态数据的获取。Sigar.jar包是通过本地方法来调用操作系统...
在面向对象的程序设计中,这些行为用方 法实现。 在 OOP 技术中,对象充当了一个很重要的角色。对象的数据是组成对象的核心,而方法 则环绕这个核心并隐藏在对象之中。 2.2.2 封装 "封装"是 OOP 语言的优点之...
这样希望大家不至于迷惑为什么总报错找不到类文件,不管是自己写的还是导入的第三方的jar文件(J2ee中经常需要导入的)。 3. 关于jdk和jre?? 大家肯定在安装JDK的时候会有选择是否安装单独的jre,一般都会一起安装...
� 由于采用了 Java 作为应用开发语言,目前可用的传统第三方应用还很少,但由于 Android 是一款完全 开 源的移动计算平台,相信第三方应用会很快的丰富起来。 � Google 提供了一套 Java 核心包 (J2SE 5,J2SE 6) 的...
第三章 编写第一个应用程序 .20 3.1 Welcome 程序 .20 3.2 代 码 分 析 .20 3.3 运 行 程 序 .23 .4 添 加 注 释 .25 3.5 小 结 .27 第二部分 C#程序设计基础.28 第四章 数 据 类 型 .28 4.1 值 类 型...
•总之,第一步先找局部变量,第二步,内部类的属性,第三步。外部类的属性。 本文原创作者:pipi-changing 本文原创出处:http://www.cnblogs.com/pipi-changing/ 静态内部类 •如果用...
void *malloc(long numbytes):该函数负责分配 numbytes 大小的内存,并返回指向第一个字节的指针。 void free(void *firstbyte):如果给定一个由先前的 malloc 返回的指针,那么该函数会将分配的空间归还给进程的...