- 浏览: 773011 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (208)
- Java (77)
- JavaScript (16)
- UML (1)
- Spring (24)
- Hibernate (11)
- J2EE部署 (18)
- 操作系统 (13)
- struts (11)
- jsp (3)
- J2EE (34)
- 数据库 (22)
- tomcat (4)
- apache (2)
- MyEclipse (13)
- Linux (14)
- Ext (6)
- Weblogic (2)
- 数据库 Oracle 空表导出 (1)
- Oracle (3)
- 编码 乱码 (1)
- 多线程 (5)
- jQuery (2)
- Apache Mina (1)
- ibatis (6)
- abator (1)
- svn (1)
- jvm (1)
- ERwin (2)
- mysql (2)
- ant (1)
- memcache (1)
- dubbo (1)
- PowerDesigner (1)
最新评论
-
di1984HIT:
Shallow heap & Retained heap -
tinguo002:
非常感谢 , 太棒了。
Spring注解方式,异常 'sessionFactory' or 'hibernateTemplate' is required的解决方法 -
白天看黑夜:
Apache Mina Server 2.0 中文参考手册(带 ...
Apache Mina – 简单的客户端/服务端应用示例 -
wumingxingzhe:
好文
Shallow heap & Retained heap -
di1984HIT:
学习了!!
工作流(Workflow)和BPM的不同
转自:http://blog.csdn.net/fh13760184/archive/2009/05/06/4153734.aspx
当执行的外部命令没有任何输出的时候,这段代码运行正常,但如果执行的外部命令有输出的时候,这段程序就会挂起,估计是因为流没有被读取导致了堵塞,于是把代码改为
但是我在windows上执行这样的调用的时候却总是在while那里被堵塞了,结果造成 程序在执行了一会后不再执行,这里从官方的参考文档中我们可以看到这是由于缓冲区的问题,由于java进程没有清空 程序写到缓冲区的内容,结果导致程序一直在等待。在网上也查找了很多这样的问题,不过说的都是使用单独的线程来进行控制,我也尝试过很多网是所说的方法,可一直没起什么作用。下面就是我的解决方法了,注意到上述代码中的红色部分了么?这里就是关键,我把它改成如下结果就可以正常运行了。
我把它改成获取错误流这样进程就不会被堵塞了,而我之前一直想的是同样的命令我手动调用的时候可以完成,而java调用却总是完成不了,一直认为是getInputStream的缓冲区没有被清空,不过问题确实是缓冲区的内容没有被清空,但不是getInputStream的,而是getErrorStream的缓冲区,这样问题就得到解决了。所以我们在遇到java调用外部程序而导致线程阻塞的时候,可以考虑使用两个线程来同时清空process获取的两个输入流,如下这段程序:
通过这样我们使用一个线程来读取process.getInputStream()的输出流,使用另外一个线程来获取 process.getErrorStream()的输出流,这样我们就可以保证缓冲区得到及时的清空而不担心线程被阻塞了。当然根据需要你也可以保留 process.getInputStream()流中的内容,这个就看调用的程序的处理了。我在windows下调用FFmpeg程序进行视频转换的时候就是通过这样来解决线程被堵塞的问题的,呵呵~
Process p = Runtime.getRuntime().exec("my command ..."); int c = p.waitFor(); if (c != 0) { System.out.prinln("处理失败"); BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream())); for (String line = br.readLine(); line != null; line = br.readLine()) { System.out.println(line); } }
当执行的外部命令没有任何输出的时候,这段代码运行正常,但如果执行的外部命令有输出的时候,这段程序就会挂起,估计是因为流没有被读取导致了堵塞,于是把代码改为
public void test() throws IOException, InterruptedException { Process p = Runtime.getRuntime().exec("command..."); String errorMsg = readInputStream(p.getErrorStream()); String outputMsg = readInputStream(p.getInputStream()); int c = p.waitFor(); if (c != 0) { System.out.println("处理失败:" + errorMsg); }else {//print command output System.out.println(outputMsg); } } private String readInputStream(InputStream is) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(is)); StringBuffer lines = new StringBuffer(); for (String line = br.readLine(); line != null; line = br.readLine()) { lines.append(line); } return lines.toString(); }
但是我在windows上执行这样的调用的时候却总是在while那里被堵塞了,结果造成 程序在执行了一会后不再执行,这里从官方的参考文档中我们可以看到这是由于缓冲区的问题,由于java进程没有清空 程序写到缓冲区的内容,结果导致程序一直在等待。在网上也查找了很多这样的问题,不过说的都是使用单独的线程来进行控制,我也尝试过很多网是所说的方法,可一直没起什么作用。下面就是我的解决方法了,注意到上述代码中的红色部分了么?这里就是关键,我把它改成如下结果就可以正常运行了。
InputStream is = process.getErrorStream(); // 获取ffmpeg进程的输出流
我把它改成获取错误流这样进程就不会被堵塞了,而我之前一直想的是同样的命令我手动调用的时候可以完成,而java调用却总是完成不了,一直认为是getInputStream的缓冲区没有被清空,不过问题确实是缓冲区的内容没有被清空,但不是getInputStream的,而是getErrorStream的缓冲区,这样问题就得到解决了。所以我们在遇到java调用外部程序而导致线程阻塞的时候,可以考虑使用两个线程来同时清空process获取的两个输入流,如下这段程序:
…… Process process = Runtime.getRuntime.exec(command); // 调用外部程序 final InputStream is1 = process.getInputStream(); new Thread(new Runnable() { public void run() { BufferedReader br = new Buffered(new InputStreamReader(is)); while(br.readLine() != null) ; } }.start(); // 启动单独的线程来清空process.getInputStream()的缓冲区 InputStream is2 = process.getErrorStream(); BufferedReader br2 = new Buffered(new InputStreamReader(is2)); StringBuilder buf = new StringBuilder(); // 保存输出结果流 String line = null; while((line = br.readLine()) != null) buf.append(line); // 循环等待ffmpeg进程结束 System.out.println("输出结果为:" + buf); ……
通过这样我们使用一个线程来读取process.getInputStream()的输出流,使用另外一个线程来获取 process.getErrorStream()的输出流,这样我们就可以保证缓冲区得到及时的清空而不担心线程被阻塞了。当然根据需要你也可以保留 process.getInputStream()流中的内容,这个就看调用的程序的处理了。我在windows下调用FFmpeg程序进行视频转换的时候就是通过这样来解决线程被堵塞的问题的,呵呵~
发表评论
-
Eclipse,javaw 通过Proxifile代理ipv6协议问题解决
2015-03-17 18:06 2798myeclipse2010升级到myeclipse2014之后 ... -
初始化EHcache CacheManager时报java.net.UnknownHostException
2014-11-13 11:45 12510工程启动时,报一下异常: [wdfportal] [201 ... -
tomcat7可能带来的问题
2013-06-27 00:31 9841、struts标签校验更加严格,如果struts标签中存在嵌 ... -
iBatis执行insert后返回主键
2013-01-18 23:55 1652iBatis插入数据后,返回主键。级联操作很有用。省去了一次的 ... -
Shallow heap & Retained heap
2012-05-16 17:09 49331所有包含Heap Profling功能的工具(MAT, You ... -
Abator —— IBatis 代码生成工具
2012-04-03 18:31 19361、在eclipse安装abator插件http://ibat ... -
使用Eclipse远程调试Tomcat
2012-03-23 22:56 1512有些时候,调试不得不用外网,比如说做支付宝的支付接口,服务器后 ... -
Java compiler level does not match the version of the installed Java project fac
2012-03-02 11:32 1322问题现象:项目图标报错“Java compiler level ... -
WebService的事务处理
2012-03-01 15:03 1562如果你只是要解决两个系统之间的事务同步问题,可以采用判断服务是 ... -
线程池(java.util.concurrent.ThreadPoolExecutor)的使用
2012-02-29 15:50 2509一、简介 线程池类为 j ... -
myeclipse 颜色设置(保护视力)
2012-02-28 09:29 20911.window -> Preferences -> ... -
Quartz表达式解析
2012-02-08 14:40 809字段 允许值 允许的特 ... -
使用iBatis中报 java.sql.SQLException: 无效的列类型异常
2011-12-15 14:46 2244<!--Content表 插入应的 ... -
非常有用的proxool属性详细解说
2011-12-13 16:19 1612Proxool连接池是sourceforge下的一个开源项目, ... -
在工程中查找自己修改的所有代码
2011-12-09 17:41 1049在工程中查找自己修改的所有代码的方法: 1.工程右键 -&g ... -
如何在Eclipse中安装和使用ibatis插件Abator
2011-12-01 21:26 49761、获得abator: http://ibatis. ... -
newCachedThreadPool线程池
2011-11-20 11:35 43037public static ExecutorService n ... -
Apache Mina – 简单的客户端/服务端应用示例
2011-11-19 23:49 5530转自http://javasight.net/2011/05/ ... -
Class.forName()、Class.forName().newInstance() 、New 三者区别!
2011-11-15 09:18 1263终于明白为什么加载数据库驱动只用Class.forName() ... -
Apache MINA 快速入门指南
2011-11-13 12:04 1662最近用到Socket套接字编程,在服务器监听方面还没有具体思路 ...
相关推荐
这个例子就是关于如何在Android应用程序中调用系统自带的文件管理器。以下是对这个主题的详细解释: 一、Android系统文件管理器介绍 Android系统自带的文件管理器是用于查看、组织和操作设备上存储的文件和目录的...
Java Web的异步处理机制就是为了缓解这个问题,它允许服务器不立即返回响应,而是先将请求挂起,去处理其他请求,待后台任务完成后再回调通知客户端。 1. **Servlet 3.0 异步处理**: Servlet 3.0引入了异步处理...
sleep() 方法将线程挂起一段时间,而 wait() 方法将线程挂起,直到其他线程调用 notify() 或 notifyAll() 方法。 13. Java 有没有 goto? Java 语言中没有 goto 语句,但是可以使用 break、continue 和 return ...
这种方法无需调用外部命令,所有的编译操作都在Java虚拟机内部完成。 **核心步骤**: 1. **获取编译器实例**:通过`ToolProvider.getSystemJavaCompiler()`方法获得当前JVM中的`JavaCompiler`实例。 2. **构建编译...
- `suspend <threadid>`:挂起指定线程。 - `resume <threadid>`:恢复指定线程。 - `where <id>`:显示指定线程的调用堆栈。 - `print <id>`:打印变量值。 - `dump <id>`:保存变量值到文件。 - `stopin ...
- `resume()`方法用于恢复之前被挂起的线程。 9. **包导入** - 要使用输入/输出操作的程序,必须要导入`java.io`包。 - **知识点扩展**: - Java标准库中的`java.io`包包含了大量用于处理输入输出操作的类和...
当一个线程调用read或write方法时,如果数据尚未准备好,那么这个线程会被挂起,即进入阻塞状态,直到数据准备就绪。这种方式简单直观,但存在效率问题,因为线程在等待数据期间无法执行其他任务。 例如,服务器...
其他方法如`turnOnPc()`, `turnOffPc()`, 和 `hitchPc()`模拟了打开、关闭和挂起计算机的操作。这些方法接收参数,并返回表示操作结果的字符串。 此外,我们看到了类有两个构造函数。一个默认构造函数(无参构造...
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。 20、abstract class和interface有什么区别? ...
它们主要负责程序与外部世界的通信,包括读取文件、网络数据交换等。本文将深入探讨NIO(New Input/Output)与IO的区别,以及NIO中的关键概念——Channel、Buffer以及它们如何协同工作。 知识点1:NIO与IO的区别 IO...
- **阻塞/非阻塞**: 阻塞I/O在等待时会挂起线程,而非阻塞I/O则不会。 - **同步/异步**: 同步I/O是指I/O操作完成之前线程会被阻塞,而异步I/O则是非阻塞的。 - **四种模型**: 阻塞I/O、非阻塞I/O、多路复用I/O...
应妥善处理这些输出,避免程序因未捕获的异常而挂起。 2. **进程管理**:执行的外部进程可能会创建子进程。如果需要确保所有相关进程都被结束,可能需要使用更复杂的逻辑来跟踪和终止它们。 3. **权限问题**:终止...
- 挂起:线程被阻塞或等待资源。 - 结束:线程执行完毕。 9. **`synchronized`与`Lock`的比较**: - 相同:都提供线程同步,防止数据竞争。 - 不同:`Lock`提供更细粒度的控制,需手动获取和释放锁,且在`...
- 线程有就绪、运行、synchronized阻塞、wait/sleep挂起和结束等状态。 - 线程状态转换受`synchronized`、`wait()`和`notify()`等方法影响。 6. **面向对象的特征**: - 封装:隐藏实现细节,提供公共接口供外部...
- 新建、就绪、运行、睡眠、等待、挂起、恢复、阻塞和死亡。 22. **串行化**: - 用于持久化对象,标记为`Serializable`的类可以被序列化。注意循环引用可能导致问题。 23. **线程同步**: - 通过`synchronized...
### Java面试宝典2010版知识点解析 #### 一、Java基础部分 ##### 1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? - **答案**:可以包括多个类,但是只能有一个公共(`public`)类,并且...